package org.bouncycastle.pqc.jcajce.provider.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import junit.framework.TestCase;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.jcajce.interfaces.SLHDSAKey;
import org.bouncycastle.jcajce.interfaces.SLHDSAPrivateKey;
import org.bouncycastle.jcajce.spec.ContextParameterSpec;
import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.crypto.slhdsa.SLHDSAParameters;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.FixedSecureRandom;

/**
 * Test cases for the use of SLH-DSA with the provider.
 */
public class SLHDSATest
    extends TestCase
{
    // test vector courtesy the "Yawning Angel" GO implementation and the SUPERCOP reference implementation.
    static private final byte[] msg = Strings.toByteArray("Cthulhu Fthagn --What a wonderful phrase!Cthulhu Fthagn --Say it and you're crazed!");

    static private final String[] names = new String[] {
        "SLH-DSA-SHA2-128F",
        "SLH-DSA-SHA2-128S",
        "SLH-DSA-SHA2-192F",
        "SLH-DSA-SHA2-192S",
        "SLH-DSA-SHA2-256F",
        "SLH-DSA-SHA2-256S",
        "SLH-DSA-SHAKE-128F",
        "SLH-DSA-SHAKE-128S",
        "SLH-DSA-SHAKE-192F",
        "SLH-DSA-SHAKE-192S",
        "SLH-DSA-SHAKE-256F",
        "SLH-DSA-SHAKE-256S",
        "SLH-DSA-SHA2-128F-WITH-SHA256",
        "SLH-DSA-SHA2-128S-WITH-SHA256",
        "SLH-DSA-SHA2-192F-WITH-SHA512",
        "SLH-DSA-SHA2-192S-WITH-SHA512",
        "SLH-DSA-SHA2-256F-WITH-SHA512",
        "SLH-DSA-SHA2-256S-WITH-SHA512",
        "SLH-DSA-SHAKE-128F-WITH-SHAKE128",
        "SLH-DSA-SHAKE-128S-WITH-SHAKE128",
        "SLH-DSA-SHAKE-192F-WITH-SHAKE256",
        "SLH-DSA-SHAKE-192S-WITH-SHAKE256",
        "SLH-DSA-SHAKE-256F-WITH-SHAKE256",
        "SLH-DSA-SHAKE-256S-WITH-SHAKE256",
    };

    public void setUp()
    {
        if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null)
        {
            Security.addProvider(new BouncyCastlePQCProvider());
        }
        Security.addProvider(new BouncyCastleProvider());
    }

    public void testParametersAndParamSpecs()
        throws Exception
    {
        for (int i = 0; i != names.length; i++)
        {
            assertEquals(names[i], SLHDSAParameterSpec.fromName(names[i]).getName());
        }

        SLHDSAParameters slhdsaParameters[] = new SLHDSAParameters[]
            {
                SLHDSAParameters.sha2_128f,
                SLHDSAParameters.sha2_128s,
                SLHDSAParameters.sha2_192f,
                SLHDSAParameters.sha2_192s,
                SLHDSAParameters.sha2_256f,
                SLHDSAParameters.sha2_256s,
                SLHDSAParameters.shake_128f,
                SLHDSAParameters.shake_128s,
                SLHDSAParameters.shake_192f,
                SLHDSAParameters.shake_192s,
                SLHDSAParameters.shake_256f,
                SLHDSAParameters.shake_256s,
                SLHDSAParameters.sha2_128f_with_sha256,
                SLHDSAParameters.sha2_128s_with_sha256,
                SLHDSAParameters.sha2_192f_with_sha512,
                SLHDSAParameters.sha2_192s_with_sha512,
                SLHDSAParameters.sha2_256f_with_sha512,
                SLHDSAParameters.sha2_256s_with_sha512,
                SLHDSAParameters.shake_128f_with_shake128,
                SLHDSAParameters.shake_128s_with_shake128,
                SLHDSAParameters.shake_192f_with_shake256,
                SLHDSAParameters.shake_192s_with_shake256,
                SLHDSAParameters.shake_256f_with_shake256,
                SLHDSAParameters.shake_256s_with_shake256
            };

        for (int i = 0; i != names.length; i++)
        {
            assertEquals(names[i], SLHDSAParameterSpec.fromName(slhdsaParameters[i].getName()).getName());
        }
    }

    public void testKeyFactory()
        throws Exception
    {
        KeyPairGenerator kpGen44 = KeyPairGenerator.getInstance("ML-DSA-44");
        KeyPair kp44 = kpGen44.generateKeyPair();

        KeyFactory kFact = KeyFactory.getInstance("HASH-SLH-DSA", "BC");

        ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[] {
            NISTObjectIdentifiers.id_slh_dsa_sha2_128f,
            NISTObjectIdentifiers.id_slh_dsa_sha2_128s,
            NISTObjectIdentifiers.id_slh_dsa_sha2_192f,
            NISTObjectIdentifiers.id_slh_dsa_sha2_192s,
            NISTObjectIdentifiers.id_slh_dsa_sha2_256f,
            NISTObjectIdentifiers.id_slh_dsa_sha2_256s,
            NISTObjectIdentifiers.id_slh_dsa_shake_128f,
            NISTObjectIdentifiers.id_slh_dsa_shake_128s,
            NISTObjectIdentifiers.id_slh_dsa_shake_192f,
            NISTObjectIdentifiers.id_slh_dsa_shake_192s,
            NISTObjectIdentifiers.id_slh_dsa_shake_256f,
            NISTObjectIdentifiers.id_slh_dsa_shake_256s,
            NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128f_with_sha256,
            NISTObjectIdentifiers.id_hash_slh_dsa_sha2_128s_with_sha256,
            NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192f_with_sha512,
            NISTObjectIdentifiers.id_hash_slh_dsa_sha2_192s_with_sha512,
            NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256f_with_sha512,
            NISTObjectIdentifiers.id_hash_slh_dsa_sha2_256s_with_sha512,
            NISTObjectIdentifiers.id_hash_slh_dsa_shake_128f_with_shake128,
            NISTObjectIdentifiers.id_hash_slh_dsa_shake_128s_with_shake128,
            NISTObjectIdentifiers.id_hash_slh_dsa_shake_192f_with_shake256,
            NISTObjectIdentifiers.id_hash_slh_dsa_shake_192s_with_shake256,
            NISTObjectIdentifiers.id_hash_slh_dsa_shake_256f_with_shake256,
            NISTObjectIdentifiers.id_hash_slh_dsa_shake_256s_with_shake256,
        };

        for (int i = 0; i != names.length; i++)
        {
            KeyPairGenerator kpGen = KeyPairGenerator.getInstance(names[i]);
            KeyPair kp = kpGen.generateKeyPair();

            tryKeyFact(KeyFactory.getInstance(names[i], "BC"), kp, kp44, "2.16.840.1.101.3.4.3.17");
            tryKeyFact(KeyFactory.getInstance(oids[i].toString(), "BC"), kp, kp44, "2.16.840.1.101.3.4.3.17");
        }
    }

    private void tryKeyFact(KeyFactory kFact, KeyPair kpValid, KeyPair kpInvalid, String oid)
        throws Exception
    {
        kFact.generatePrivate(new PKCS8EncodedKeySpec(kpValid.getPrivate().getEncoded()));
        kFact.generatePublic(new X509EncodedKeySpec(kpValid.getPublic().getEncoded()));

        try
        {
            kFact.generatePrivate(new PKCS8EncodedKeySpec(kpInvalid.getPrivate().getEncoded()));
            fail("no exception");
        }
        catch (InvalidKeySpecException e)
        {
            assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage());
        }
        try
        {
            kFact.generatePublic(new X509EncodedKeySpec(kpInvalid.getPublic().getEncoded()));
            fail("no exception");
        }
        catch (InvalidKeySpecException e)
        {
            assertEquals("incorrect algorithm OID for key: " + oid, e.getMessage());
        }
    }

//    public void testSphincsDefaultKeyGen()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");
//
//        kpg.initialize(new SLHDSAKeyGenParameterSpec(), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        SLHDSAKey pub = (SLHDSAKey)kp.getPublic();
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub.getKeyData()));
//
//        SLHDSAKey priv = (SLHDSAKey)kp.getPrivate();
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv.getKeyData()));
//
//        KeyFactory keyFact = KeyFactory.getInstance("SLH-DSA", "BC");
//
//        SLHDSAKey pub2 = (SLHDSAKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub2.getKeyData()));
//
//        SLHDSAKey priv2 = (SLHDSAKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv2.getKeyData()));
//    }

    public void testPrivateKeyRecovery()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, new RiggedRandom());

        KeyPair kp = kpg.generateKeyPair();

        KeyFactory kFact = KeyFactory.getInstance("SLH-DSA", "BC");

        SLHDSAKey privKey = (SLHDSAKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded()));

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ObjectOutputStream oOut = new ObjectOutputStream(bOut);

        oOut.writeObject(privKey);

        oOut.close();

        ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray()));

        SLHDSAKey privKey2 = (SLHDSAKey)oIn.readObject();

        assertEquals(privKey, privKey2);

        assertEquals(kp.getPublic(), ((SLHDSAPrivateKey)privKey2).getPublicKey());
        assertEquals(((SLHDSAPrivateKey)privKey).getPublicKey(), ((SLHDSAPrivateKey)privKey2).getPublicKey());
    }

    public void testPublicKeyRecovery()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, new RiggedRandom());

        KeyPair kp = kpg.generateKeyPair();

        KeyFactory kFact = KeyFactory.getInstance("SLH-DSA", "BC");

        SLHDSAKey pubKey = (SLHDSAKey)kFact.generatePublic(new X509EncodedKeySpec(kp.getPublic().getEncoded()));

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ObjectOutputStream oOut = new ObjectOutputStream(bOut);

        oOut.writeObject(pubKey);

        oOut.close();

        ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray()));

        SLHDSAKey pubKey2 = (SLHDSAKey)oIn.readObject();

        assertEquals(pubKey, pubKey2);
    }

//    public void testSphincsDefaultSha2KeyGen()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");
//
//        kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA512_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        SLHDSAKey pub = (SLHDSAKey)kp.getPublic();
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub.getKeyData()));
//
//        SLHDSAKey priv = (SLHDSAKey)kp.getPrivate();
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv.getKeyData()));
//
//        KeyFactory keyFact = KeyFactory.getInstance("SLH-DSA", "BC");
//
//        SLHDSAKey pub2 = (SLHDSAKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub2.getKeyData()));
//
//        SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(pub2.getEncoded());
//
//        assertEquals(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512_256), SLHDSAKeyParams.getInstance(pkInfo.getAlgorithm().getParameters()).getTreeDigest());
//
//        SLHDSAKey priv2 = (SLHDSAKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv2.getKeyData()));
//    }
//
//    public void testSphincsDefaultSha3KeyGen()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");
//
//        kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA3_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        SLHDSAKey pub = (SLHDSAKey)kp.getPublic();
//
//        assertTrue(Arrays.areEqual(expSha3Pub, pub.getKeyData()));
//
//        SLHDSAKey priv = (SLHDSAKey)kp.getPrivate();
//
//        assertTrue(Arrays.areEqual(expSha3Priv, priv.getKeyData()));
//
//        KeyFactory keyFact = KeyFactory.getInstance("SLH-DSA", "BC");
//
//        SLHDSAKey pub2 = (SLHDSAKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha3Pub, pub2.getKeyData()));
//
//        SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(pub2.getEncoded());
//
//        assertEquals(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256), SLHDSAKeyParams.getInstance(pkInfo.getAlgorithm().getParameters()).getTreeDigest());
//
//        SLHDSAKey priv2 = (SLHDSAKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha3Priv, priv2.getKeyData()));
//    }
//
//    public void testSphincsSha2Signature()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");
//
//        kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA512_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        Signature sig = Signature.getInstance("SHA512withSPHINCSPlus", "BC");
//
//        sig.initSign(kp.getPrivate());
//
//        sig.update(msg, 0, msg.length);
//
//        byte[] s = sig.sign();
//
//        assertTrue(Arrays.areEqual(expSha2Sig, s));
//    }
//
//    public void testSphincsSha3Signature()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");
//
//        kpg.initialize(new SLHDSAKeyGenParameterSpec(SLHDSAKeyGenParameterSpec.SHA3_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        Signature sig = Signature.getInstance("SHA3-512withSPHINCSPlus", "BC");
//
//        sig.initSign(kp.getPrivate());
//
//        sig.update(msg, 0, msg.length);
//
//        byte[] s = sig.sign();
//
//        assertTrue(Arrays.areEqual(expSha3Sig, s));
//    }
//


    public void testSphincsRandomSigSHA2()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")));

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();
        byte[] expected = Hex.decode("7c65a4abed5a4926316228c52d815b0086c8fe9991254a563db365e340d056dabe5b45ce9e46f8c64fe65644d3874ccc9ce314b2d12d4903188c110fd21a6e548aa995f2c6508be8b60d620a906a0c3e394f31003ee12576d9847c508125058d1f030dd91c5da0026190f3b0f5d18051621c87c0334c644552ed94dfd8868a13ad90d67471f6ab3891a0a8a3a374500faf30f22c56bde568a89736d0a03203a23ca48135c86939f4e9e3ece6e3be79e18d33bed0b3ce7ee69922e08c0a7ecb1375ec93b0393b7dd4a3d64a8c030d3e7bf144666fbb67400fd38fb3b788460eed49439fb2093a01c21cdcef6f2ddfe299a3bd3d675949c3c04390a9f39c1a0f4e99e6c49cc8fa3728c0b9fdffddcf560b791c00e41a09c3baf99b192d519bb6e095045795ecaf4299bd286fdcb27045ab863888807361a7497f24e014618376041a49049fdb572b19d0da9ac4d35a7fb6a9d18cffe0f6edde17be904747fced7b670d7b0aa8f4706facd6e1fda80b08f62fe2033889bbe15e40995f71dac567b962927c16a08c1c2141e5d5eab881306754c7367849195538a8c05eef8bd1036962aa6a227cdc3772d3f9c142f7f74661c2daf6a094948765247a0c760851b731077496222121b5e7c852ab0021d37a4743242d96874d6a58ccfe07490415b482de7ab164dfb19056c93bca1c0260733f93ca7294e25c7bb117aa37101d705806ac8558d3ea9abf90a500081b77b657c515e2eca4b3058a3e9b63fa8b7a83d0be55828fa4f12e7cf663624224026ae8935f1b99b92128c5ef154080f66cd361c22d020dea778aa400011d212900a730e45039dbaf9f92ab4cb02aea28f1ea0ea456c399017b1a7ed410874aebdaa94cd8f54f16abd4b0193614c5b2f4d28bd3fac84e4881c1c92db162d9a441bbcf668b8acb050721ef22e79c7f9fe8675dc3501c7dfeb8f691d5ce390905d3bb0b523c1ba4694e0982669ec0a96aaf2b0f72df752dc627d71cecfc027e59d3ed440776831e2a8ea09436a504bd30c2b5bed18e4d5fe270bc5ec98e2ccec4f2f33b864f7912f45502b6aae2a9275e4049c7e872887a307cae2a0076b1c74cfbdc1ea8ba6947e683caaed96e84f451ef643e4d766e18ba6dd05e7ac46432957bc141deb48940261200444ad2e6b8b7fd5895c7a4e80b494bd1b648b145de29b718c7768f16dbfbb9dae1c6f991a57664aee425b12796d3739c18d532c9b3c37e8b634b16fff898aad91fa3b20853183dc6ecd535db1d953f421c2a195e781763f7c8117c6204b8f27d5ca74873c5755fdb96101b8a43e430207ff7d1a661bfac71f4261080df592a700f6c687b788230cabbd240f000fbeead9d5124dfaab331b709ab4165efc89a108fc5962a40989b8b413140196470e723ba6c45fa94dea7d4ed45c7fdbcbab9c3878493ee44ad35bbdbb77553ed2fd9e7a20dfa55f1875d232333935bd529eb1dd1d3a2f5f0b291c31d3231a719ec794059a89ecb2f12fd6bf8b227bcaabf0d43a9791f8f9190c31da568df59774be74178e08a80cd77ee6ed3024e3f530a4a32f2f36e2369b6a7e9d7411b2233e7a1e80e43b208324daa82bfea001311e00ebf9ce6631ab067e42a411597db903552261c289a619a459185a44a3cd26fd72d942df7a14434c0afc1a4bde8064315973d26c359c774bc3e4ca183c6f9b5c60c5a0566156ae9cea689e4ff1364b491d5b49a18712a468a2298994e006378bc9fc0eec56697b24dd0c4e2ca2d4bc52f3fa995df91b158ea726526700100067ec6a419571dc6a64bd5d526aad6f375891a04d8d81e2204bb3fdf7ce553aa90e07e02d3014bdc16b9a3d08f5d63880a36e13c30790ae3c7cfeb67061bce2138d1b9124a95b1f5c3c0f20aceeb7c311a03a0ae11574890dc998b54ec0145411c773340b96a5a6da30fd9ee7b56142414478e0a78f9defb187f8155e6632e13e272f8314621214e5d552dc4de3c8242d618919f000f0646a86ab494d9e0b840f13a457449e95e7803de4897b2545fccba471c44b8bbb760e84d173518672aadccccbe7e8cba8681e78067fe63bd83f26afc04fe93a00923fd73707682c377458bde04d4a8b4a0f350f6eac59c10c8ef739e4568c9044bd3d22182e881bbd8f727a45e1d7e666befe8c3640d325284c29bc22f3103ba468e9dbced0c9025a18248bd822d4652a756b6643b18590c6af2a3d77f72061d2ecefeeffb7fd0f770cd022922c72454d3bd4ceee3782901a5efcadd2b899a92a5099caf8ed66bf182d6457e3279811cb712cb269ae6a484626f27d86638c586da27fb6d5cd1fc2ecffe7603fefb346e76db89b9b714f3e0cfc3b5d7da68ab332371d3bad9dcdcdd294519374779b0fc0216f2a2c938403eea1a501906991c55233eeb63374273076a72f77144a06bb67cfa70babc7fe5f6739a9e808c7643bcad6f20da03f6071d7296d601a4142d2bb9f015c7adfde3765e011097e5ad4b29dbe47a50f24732370a1b471ed304e7d0eef3a2598e470e60d8d61af0f68b10a10543182abec726f27a452fdb4f669b02c908349e0da297a5af613f5e5d48ccd83ca4be57e6ff79ddf74b31ad8ae715abc8b1284e1caedce4928925301b538aedc0e38fcce10fc91968ba8a68302755b9f591bc179e3e31e5f820110328dcd58d46cfb71a1fc29b51f00dbc078fccfe00e6eeed39bb49a846e2f3674cf79b9b208d726ed0615a5498d8883bde48de23336a13935a38fb95a762ecf4ab53883dc434b4515e997a408494ea2f2abcda0fe24b4e9395de6cab707d924de8a3323de5057c8047f97ca27f9294aa319f760ba5f78a3c834e96bf89a3284cc584139503665a2813944fb3705aee1bb866cf5defa5b26c9d9169286fc56adf455f6c6838a2cf20358dcc081ae06079eed74b3fca1ff617e24fc2b8fbad7aad505ad1de9105bd59da2afe2cefceb4e7d7ba5cdcb3a43a40b06376ec8f7921e9b4abe571d2a62015107d107bc7f41b01a0eae20e9495b4b490cf9dd451201828e8ec4f9bd3840570b637adb24d979d361be7940fe570bfae66f0dcbabf1ae78fa516d106e2f980a74a39f10b1f00b1e96046eca047b471a212b26027b5b13853a2eded38d148e0d8c98be3aca48f0f581e9ae091830500217bd4809c5ca3d38f5939fafccd29aa875afc61fdcf96a1b8e207268693d8748068b9bfd73778f5338f772cf0287322cfff67f7a2f02f16fe0c5c0edfb0a4a10dbed23f62a6324c84cf06c3277c8dcbaae6dff3130d3af025a41e0fb06d954da1ed8ee8b551001b2ce6d5dd3593acb8fd641ad822ae8ee5fdb97fab411659dc6c99c8dab505637b497269c2f8be104db9f1e8ba3002866a2bbd8f6395e6652af64ec0153060f52602b280f64563483d41c8bfbd8057ebaae1c7d43deb5355ef4f4076c9d8460784eca581dc987758440624954704190d63e77ca6ae535b9c81a1dd84f3d8d45c574617d5af921ce78c10848477730d36c849603ac80100bbc27a245c38bf9d3c04df16b0e9fb4d7afb043273ca33e5d0ba9ab71036cfffc4fc94fe8957857aebeb1c7d13462b205463a598e88c28d2155eb7cd136e86b2fbb2d453d7466887601f912402861de0239740b61980bba4cfbd12acfd7c77c74bbab585d02230492f01090ce439bb4a62d87a11d55a99fb303ee314ebfe7ce91e7a0a7a09200f3e27b07c42ac239f97bbe30b67963f3eeb86293a134b7a78978e1599529a17049b377245db909e3b4daf464862a15e38ebdbf484513717d485abf438579dc03fb7317e1d75e12e290afbb946aeaadffb449fd6b06edc3024045d9aa98932b065ad4ac89a2ca247a08c7b1c6e6f5498b083af3125e68c30c1ffb471facf43138c290be05fb29342c350bf8c8d428004cce0fc132b1e39fba0cb7e2aaadf0adfc97652ad18ea7c8dcad8aed77c7db021a4fdcb95e24b41d4ebabfa264c1d3be58ad0d5256e423b39c61b6aab8be4868d4de14cd7cd57e4e19dad9b5563298a2b718c7b6e312ccfcc37b21dd491b9f61912f05fc991df9ba558b36234e50c760ebef42f976dd42420811759b5b4acb4ad02fcfcc52a9ebf8acc042653b68c34654fde992916ea63ab346839ca1a921404269c3403c6d45f6802616cefe9beaabc5c2b4b1409de4d64f262fbad635c5690e1d536d12f0eb8776cdeace37fa2af3d2ae9ca4628386c8fc457d239ae2b12bc7517d48bb4230141554a6eb709ebf628bc79297bdec16d72e3827ea1e0041b94795ea2915294f904d69a6538475a59274c62840394665cb9dbe1f004384d6864efb17caf2602f9a3dc1eaf3191286d0dc320e796cdc75197f99667d70036f23cdde384b10bc42b80f420b92a5b68c3df9eab25d2c1e42b57c2e831f80a177fdc10037f38c700cdd0b0f9300cc9e216e77046771b8f6f40030fa6d3ed244f7ded3c05904b5f9b194d2b51475988747ee2cfe277a9736ad7362e304653b21beddac32e30d9c99ef11a809af2ae602cd1c4ff44538b3e4a5dfffe03584824d6475da866a49b0e1b9b908f78928517125f64e2e5481071c5bcbb9eb55435f8523208021d67e80cc28a33393356bb11a14f0513cfb0a835cdccde3a10af0e38da32ec25ac50b4d728b994d7e1a9147ce32a470645380c6f447c04e1a1535cb0018fd25f4e886514e617564937012da42d868f6c0f4697a26457ecd7cbdeabf298964c67ab1594e42af19a28cc4405ac968da3cabd5a34a86199ab85dab34953882b5c20d7177b4807d036d303d6140e975908fe86b9b48a4c689627f6003a6a0aa753c41f5e55c9c99516c10ca47a6ca4d8de9d5e52688f6c1715f16e731c5843a2a7979ef5c3d5b94b2530aa8eab356c62d15f189c38bfa2ae4e6488d476d85cd00166a6d100f14f44d612dd4631bf1e2732dc3b547b2e8b2946f52124695287527730744e91a491f17be7ed0ed7c060e2f053ddd837167e4d70f67455528d48ca7eb225f75184ab4e5348d3268508c1ee7da39098beb8632c50e5c71f71e2e5e651caf07ddb237d8b74801369088732a263252493ac7ac9ad4f25123e7464f5057a3fc99b19905666c43083d3f5c9265277707f27fa604a2d5e84848cfd88773b7e6a3f78981b5e34b5bb5a8bb20eca04db5a2a5c01853083ef716ce5b5981c66f5b6254d545e709b347e98a913314d2aa1e427875ad90d8930afc14ec92dd95953d7883438f66ddb38bcef5bfebfedf8182323b9ba999a6454e568963526e3f390c26e570eb90510180acac7fad3884b4b8f2b50358bc576bf9f5789db0f4bb39c486dc500ca59b425512013c1d98c06adb29c3b15e0ac9cdfe701caba233e7b7f7f4fd2035c9d642aa5932b12b57cdfa1595363e5e3f785ae7cd2fea7dd5e29decef35a048dd97a8f1736341fd0706735c746a16a1fd92ef03ee2dd5278261572d254518e65569a1fe83752c71a2cef7875b21e115da82888cf37cdc893113877ee84d69661a2b7fc34973a8dc1245d10940f62f21e80b463f6fc75795f0353dfe94d70916ae6e9bab0fcf01680d13c9f2e57d427a31f7342c591b96ef13ffdc036fc3e6d75864e2c50a676638e9e9f69c4c7a16535f4a1b36fab3b58759d83c3a668c718f88a3296d320235f9ae65e7c5811dce32d5912f2111292cbde2b2c70e6619ad5177bb4829ad7c3a4a00412a1cb3033eb930abacc7ca1bbe9ee5b50a38dde54b2533010cfa39804807449904f76d650739dbaa0b08cb72b0c3c9b29d7ceb8d0a8cea47b126617c47ce9364a6a0a083fcf5ac152c0248cf78c576886d697433e4bf6b0fa77864982435b9628f78eb2678c80899f8d413aa72dd3f59a1d373b59d85024e339bd54adc84ecccface73813e7205c3a4079402a3608f24c8fcc788c071b9dadb1068b44c19219c20a3b33ddf5ad87b223be873379d765733d5c8a05f20804b7db1b4a10154e2361f8b24debc0dcb51f6e475f52224dd5ad497364084882043a04302fa4c24fa5c0a02fcf82ae455bafcd29747ba78f1660b40446dc188cf4655c852bf3b844ec40f0c9b2cfd81299ee699564a651d8ef00198ae7d36c833fea52b1054b5a693e76d1cd6190d71dc442c071b2617b9cfe5212ccf925cab46cccac6e3cad2de50f3fc787aabffc489532a46176b39c214b245e00c9333eaad119538a171916e01a94a4d7ba42251d4f3a51d5f2919a845458fe36573238c8c5aba5d6d5c18fc3bd0776ff88561325a916d2ec985628cc9ff1381e219a0c804f94fc8906ce073fe820c2520e39e4208c88721cacc1124d9787a54456b93eee9660c16d2adc283b4cde456c66060fc4f6c683a0e92b7d048400d539ceb55ad6e38296ff0aa7cf7e1f5bf88eeeec51cd82b1735299ffc59c3a807d809d9ba1ec57d5104d95c96e1d38df42997083e70f65bde2861f830559c9c4de92ca0f1acdea5bb1394024de73453ef70c54dc26e8dfbe42be49d4af77ff08c220b75a15fef3e5ccfc6af5da4c353aaa85326b49329eb7da7fcbc58a6db318b63a44501ae04978a45266d56fa36abf81dee1beaa8c244e80872841ac772a7b8b1695b0f42a090232a61886c9cb36dfc31485cbd4486d60d15914b67103945448e93fc24b2f640ade543f393c4f7a7fac43ba6d2238eb8bd5a010b623ef9e6f1559550d2e37957fbde3ef4952ec65e403a37ae1e91da9399d6751fbddfa0e98c44f6b279e47370fdaef3b99ac02d46beed2308efdd6e0f21d8020dfefb1c46bc2f164b707ecb74d5d8763e31f4631f0231752cff0fd90c4a9565b5c512497a5cecd799a234a9989b7f1e7e26d3c57b8bb595daee9319b97b98ae080a15ed88a7d9bb47a5c6d493cdfc51b6fe54cc8577a15782776cb2c895dac267746426ff0275703cea45202c76e4d0bcf5b378a459e25c078e055bb225fc0c17555b3e28d313a25d1ca1a24cea6e5c527e3b0312a99a56d5fa80610ca6cb2e294c41eb8aee4c18a572b8e600694691b67313d5594e0e4ed7e74dd6a95e2f5c66376d2e3ea5a484f7935966d7ebbfcc99a66ba7232691d212b2a1a52f9ba586a03832e13e1da4251dd2f78e5940aa3618c6814bf544d22e28782ca9f71622acc7b8ceb73bdf7b2e3a61a3ca0a8b3c07bcd371ec3c5537650f69fd8db5f862bbb7fa2789bcdc3181dafce8dfce88ab29b1c102fe1c9892c5a57170b4c472e3627c0e7660215f63e27c1a713a4a17485b103a14d4a1ad3d5ac3051479cf699f54bc6a5e47c9654260c5d210bb083c7a7a35b7ec9b4944037cf9befc70e440a7aff4f7d68048c7b8086574f7e3a9b7ac40e4bb7787d11c435ea5e698a4409486f7fa76e2852e6f5d32ceab5d3bc75532a92adeabf09fe54453c8313956ac94e016f140df72171a07e3870ca69a33945a3beec5773578d43a3c7f3ca92b403c8a2868436440638936f859eb855a25791b789f3af3586c7313082e4f2f73a4f31888e31ed32fa2bdb7c3613442918477902f3a9742d98abe453a354a45628597139251e86e44332d2f0059805dc33ccde0621e54a1dd53293924bec6401c1296c11fd03146ada01b7c8c9357d3aeed6e2607a588fe4ade46f1e4d37c9533f7a00cc4e29184322369ea2501338859441e1e93ee09cb7b42c42e2940697402d983fc1e7fa82f9054956b09b52660bb8596b3b017252de3c9846a5cc88eed042eb59308798ca7ea6876026b4efb5494bd3ec94cce5e5ec359d4ef0c6104e256dc4a840d030c6f5828de7397d16194fe5d6124e0c08064ef3f3e7dc1f035ef9a41e35912ba68eae57c7a47e44866ba91593c6280c3da79e8613586c121e803af786f938212e76dcde4156e763934b6710205cf2e89273a371248d2c444905777aa2163196e709daf5a5ac7670bbbda5ef6b70e71dcb3f36a8474f318cf41ea4a328401f305ed3e506974c9e9a66c3822fd355420a8d7b375ba42505b5ca09d6f53f6e0b6cd677f3700bfe5cd99dc606b1d5034000dbbec8f98dd23b36ea44fae92e0b3339dce3bcdd0f4f159ddbdce13caddfefdd3683ffcfdbe05fd8e6c7f87e5f726230fc6aa3c66b752628d5580ba828c79b6ab22fdbface25f913465b76cdb58668e60db1a1d7066f60789c08d6f7bbf5b50224ad8bf0f0c097f088520b265ad6973a8a43d740f4121bc335e89c3e4b8734840d7a76b961453a2142069ce0f025be0317cd7ee341e7162792168a9efa720a3d23a7ea7e06e3d6d72710f30f617324cebefc8d0266e2d7c6c72d6bbd741abf438092c4b2f6e03444c86dcdf257c15ee2c7149f3549fd1192d5d91891af390f828f2e13a089f48e124a2ad072265f51eb46d06786afdbffa70872c907b2d3781aedb35c7264b60ac7d36f89e26c9d824511f4d35857ae084688a596e8559c7fa58d6ec13d7907fdc1f9338a3530a3ee823404da4bcfd43af2f94583b3e862555e9045bd76f5e6449635379f2d7ee80c7603866a9d28a0f0066e58451eb931984513771065d675213d44e1459d8356351fbdd3bca856e7bf15fe56507df091d40dc204e1e7cbe5fe78a02183cee906a156eee17b14763173b8df6053389e825b72fa1138e246bcd753ecaa58c31221227e8d91abc65fdf436886da67078b41ee364e1800642c437d4e7aa3388847d36ab59aa6010547f5e1d8a42858a777b97c6ea621980862114f1691248f122a63315c13c0312d72227394a3cf380ed5673bb749e0f188e1d53a74c3e0e3f63740683d6922f5354fc42f53cc97d7d0459767737ab89b6857bb456edf86fd874c9485051dda317c7d69d59f134271496bf4a6f59d402c03701f94c593dd9b61c18ce8493a8606fe7e53d3fd22da8524a8fa7fe91aad2d1eaf8d38f7f9e71c122b5f19fc483f73b041d95671c2c1269b2a6f319c1f2b76cdaea1341f69cace60c78e01b0544879381e672fc868084063d5b521d69729986b282dd8da32a221c816b270e520291de331230dda01af303af4e65f2cb949431040dbdf81afc6d1a2acdf39b722c2506d85bef9d7f06f383feb81e5bffb2c12a50f2ab8c1d38c5045734e2f66f4bc2a3b4f5d745f1b80094a5487e2452428746e0f286d4c1610f1cd3c238365eaa69e32e8cbd67b11882b014e86cd9578ba129ed9a42c3878e2f223277d36875c8dbaac008498c2ed97bbb9a05406ca9d94fafef817ff487254941fae9d0e797d77b6f7cc14f1f91f37b4a395d8cfcc0e85773a563da922b905fd70cd994f887543bc6c35a0e8210e239137959ab8380a8f6ae259bd039032cea1efa68bf9c82efd42747a3c5eddd7bccbc0c96d69dbf12671d4ed7455939d4dabee64f11655c548650198caba28f0a618e240ba9e20adcbcdb97251485c0843e11860d3f9a117de40e7d30e764d8b5839a0da0e1024991702c700cdfef8d5af8563f457d0bf48a44a7f0e9d51ea13b8903bac1a3f3933690d2ceb99fd26a183ec5d6101c34c6894fc1b6bd1da0ffab09b0a8bbbf9c54cd2760d88650695386c33aa62b6913df7f814023a3b2e56aa4304ae05b7935f1203366df7acab75f2078c2bb5e6b01312e3ac5cfebb1054c272487134411408098f26c26fb5f181410c5115b997b82dfda05b0e6a9fa5ee6469791b0548984aea213b312cd9cf5cc64a6a3880574c64db1e93ec482252b618d2d3355d37b581d21fc99f3973e9a76fc7fea9c96d1f02ef751a756d23bb2c63778bf5d042b38f2b89522db9f7abb31948950256ab520e0d3b511d6907115aec631d3a797fbc125549109c055f89818ed4f3723db8c8ca0d8d6bf31ce9f3acbf11ca5905cf5cb1f237c661925297722048ff1b51e772c35f90edb3c05b51ca0f6446c7bf1a672bff344a9d538ad4896212448352a0cc1a0d365ef59f058f29a6bced30584c701508a93939dd01acc79e6119944084a4c1ac5581ae663a1b1748d3e34e8ed9f01a80a8a5d10eba4b8f789c1288e86bc660e56a16343881d9466ee869f50c93b9a11110083335b4e201fda9c537a9553048ed88e819494f9e8556eb8dff01a8b9dd6a8a4928861c69697bd1bf921249936ba7c629f202ead82365564dfd38541d3849e8ccfcbda35da37377e80a4196536049001d689ab09c8c183fdc3e8dd70eb25af0570a1a6311f1774db8c029130e78f7384872acc3733156bae2e8692543c45640d9a18905ac8b28eca38278da9564451c2f0173b4ac8071b69be625b794f9d8a4ef0ccfafedc17dd287107ebcca821761ec1d35934160522366a200ed633767128eeac83ba01e502aea183ab8e6f8f5173d5fe6d0faabf51942cc6fda2c5c3377b0c68dbc65151ffce6a09e52b4c1913fc63ea81154fbc6fe2eb99103c1bb5b7cd2b32e63b3788e71f273934c47cb7bd4f0b36550c2a5324e69b08a52a0268b4f6a254b6a33b2dca205b352fb38beeb32e5d7a27bc567b9d36188c6c0d56befe46828b01e6742067a933db93c952a960cc6bc4d8ed112be22619636a175aeae5162c0f662b6f513cd67931b44374022b8cd03c08276eab2cb171da315d77db1f38fbec7219660a4984adebd730c913a982aac5cbd9788c17ad5b6b8161d37e13a50fa1fb84076b5a6e2f4aef766f007113ce40a6652e2ee88d88b0039fe35405c5a343c4ab650128a0efe45e4216550de2187766c1b20138e31e38116e9fcb3c009c7d160ea3b78676083cc17835c049260c9c08b0d1ddc944c1b691ce7de01127011abb3478449627cb02e88f99541471218a2eaa179471d6c663618f1981b36f10a1b851aa29032f7891bf3bc1f4e3204e27a57366acf10aac8a3f48c6d12362337eb3c3b22c8a8db14ef8662ce5baca19a6a25ec56e71c8d4cd5222d3a5d4f1f6b1d48dcc769017e8d0eda431dda79cc9b120dbe3600ce95324dc3a6f02c39a31695e8aa8b91ba70e68bf1fe19f67a21cc92d241c8733da2cda68cd82d8736f7fb00177a4c8523875bd40600ad84e70559257c07bac8a7cfe62cf42f4053213d8166e49323a171e84580807dcfca4d94deee2b260b3c6a8db39de104aaf015ec3ba6fbefe6e6ff8484247d878fabda29d4ee15135d388654f7f467dcb45d4f3c4fdb33150a1b8c2a6b11e83ab03433c8bba39dd18116b58385766c5b0b9789cc0900b100bfd9a8b55c4bd22fb1edb800fc42cf0ac8e66eb4d00dbd655b582b01fc9e04dd687ea3d7ef77f8a0fa51a5a52861f10208bdc4501a075223a26d73a38592f581e918256fbba191fa7b323ec7777ee922a6b3890f5abbe262fd4d6b1ced136b1b90a8a831c10c9c0859b96f485c3b8584e0debd8a6f1bd465f95f3ce0570adb9e83059a8159628d314deb874cdb1288e97f68dff695577b60c0e31a48eb8edf6f2b36e97ae8cbf5798fff891f43bcd977b760bad6117a02ccdb4265ee9e7d433af1212ec5b1fec0798bc2a85702c03a80f398f72e42e3fe1ad008e891db37e9e40f10e0c68204c1541c1f9232d25b4a2dec8836cdb9b4df436de8d4de02b05391caf9eda959299a14f3d3c5f964d7b4ebe3b25b896a417f15fc4db4abc01e7bf32f511294319c907ff4ac46f6ec4079f0da894d7ac3fa9f02caea3f9fd96689de52f8d68694b42e7e0a87422b4ad6c148b059c7fa738e484d4f0f58154205a9903c7da97dee414a36426ef22033f72e1d7c6330cfe1372e79473a837dc4c54b2302f3a9179d5a356985ef6eab02a57b384d56389a95d175364e287eaa159cb1aaaf89e6f1c3a41a50fd245d58f5ab900f6e484d82bdab14d748d8bcf07c82925d369cf71491eb4ed699f4c6debc698fc67595e81cb7f480bf770be93df0a108598d272be9f0922a600c965cff0c044e3d6cf60cd782d47b0427d3dedb7d317f2fc988bfe9fcfa3d9232f415b014ab78d22cadfa7f9178573e5ec3f06885a68474afc40d044e46263cc066140f3a58cc9e5674d297ca1b9afc669ce1d00f081c5f7b830cd177f7fcae315cfba601f971ee9b78ab7729fa2f06e3a4cb87ebd70d172158b4b8c11096818697d3ab2110c04f6ca906789146ed495e3c119516b5f34c423ba4c1c271f288b08646e01912a7c873e8784767496dacefe1a91e28b83c2408ce8f303e4fc222991626f9f7de7484013aeea36df9cd8fd16cdd47b45fe7111de94d7d9638d1bc81ec321e833439eead1d358a61e86d070ae93cbb0e12a365985d4065b9175c2654ea66dc5a856cba6f7a36cbb7223868d1d15679c923f306114e2bd4685df2f41399ff87f252b6427594071a31204887e4764310c412f5e74a7337bece000eb22672a708e98bb7f1e5b8b5986b6252ac06b8dc3f5b0823d03241699bb49bb7182020b11888a660c2bfd3d8790879ca0a228da8d1f97586d743e98fc97199f65a0f85fa75411ededc9083272ec5b09040b525e0b1ecb6bceb038025c13e8406cc9587c80734bf7f654c23ef987a0bb5d9e1e43a3cfd97404117264900949a1034716ec90a3f983ba49fcd8f36003f36768c15e3523da2a9da1ca6eddf54da5397e3e7f02e19c1b973b9722e849625cbfef8eaac005b1928cc4ec2eef20cf7e97aae0107e7ffd94ec9014118e6f5760e1a92c5caf0c563e8dc4cc6647049dda50376e74a925a45e01311f72edabaca059c56f8c20841a45d1e84e849cfc21b393ef83ad760b53fb913cd6cb69a9d255b93ce699e2e7fba28e9759135cfaa7b56fbb721b9576d5829207309888c5363774689dba6df6df6b32a9ee4c582a86d3004c38ee18df2a92cd2bd2e17c097f4a152d4cca7ea5f388c53897d60e77a81095cf977ac1f1f959957e6c362dc108f456846790c5a109989387ed02075cd0941662bdba235ff8e0f0f1d517919622c70724af49dd78d4e59b1679d1f720ded6263e9fd6577cda41647a6de783373f825b8147296c12aeaa34355f9d380780ad1787ec9578bf2f4f5f432a9389eb9dc172766f2bd048c6026860b9135e5547ec0e5f294ac2ee4b03a68222fdbb8d39d6dfa3db7468c47caace1ddfe6f8dcf711a6def98439b82ea2aad697f3510d195da07f219abe10a5c2d9b49e057c5fc18b6cf7302ab4749d07bf5e7b4e355f41a1dbafd118ba7f7d37226f573e24f165f91de73c97db184ec186353e87d9c37957510245e522a92fef11512f620cf184a157a5beea1c4198c7aedd5db14ec49aaf7be8326e56f589beea005f3c63fe8652b8a14761c858a6e75e09eb5f3f063066039e65840c64b9d1898813639eb26185246d098d3c140d504ed99f076914bb03f3be33576fb5dcbe17e560ce4184e7e874f525f21055e933e10ba68a550f3fc233b93d5c842f9e14d2dfa51067f125eb16e99f62f0075f8f6d95c6b7601b58d3f0600714fa0d3dc0f480f5b265f3fda18dbf48110b3fc35fe0652ec3e70e9efaf16c807d793c40f977f4c52b705f450de5a26a3feea4e42714c16a7d399cc54585c4029eb7e33533c6bf4f65c08a8a33095a246024920c9505fcd4fff7235f281aef4ac50e4eb663d1d7751bd2910f09fa17d3e5d0f22829f9ed22ac715a26b508abd2a574d78405b5fbe582e5fa1198beb437e98c4dd96e46da8d99bdc8ad2b0fe3bd915eee567354a024cb632f1286d4b9d873d42d3439f52f8c9c1bc12a101e73e8f29b2c48e36cb19d23e2e9ec8fa60c98ecec823f69b95f1436e94513ae33f4c0e8a0a2999bc8283393379dc35522dda1dfa791285b79951b4c9299dfa99768fe7fd7cbad763cde44b384479dae32ede52da46e12ce5faeab2328d6402ac6354fc548e0fe655ca7ffdbfa2ce94586efd6eb1d5146090a3f79610da3558832e55766333a5f15f2eb8c33e4a352f2ce135c651d829799cec84fc44c28289b81549fdc311017ad5b37ac8388d81e9a3adb40c6910b629736e209cf7a7a87ba344353e9aebcd75577d86bf1b33f41d0e603bc9a26c803b5eea11fda2f6a4c5071001a3a865b85004b4a0d1383dfb979adfff52119df541d3c58738e7019afc60e251eb9767d4b886c9f4db147b2ee3ce9838045411a03e16240a986272618dc8ea67e5f6e1d460b7a532377552ec398a498e2385302533310f09ac49475bb77f30605ae07e1cdec9f9dc35a75ca1a4aec073ae1027dafc259a08a948e99442a335aa9ac54150bbf05caa3bccf95ee47cc8585e7932c8f0e9bc2c6880da04be7277a4f76a4b1b0b22764137527c48635eb141028d3d7991f6ac753bd1721f82d72bcc5bae307bd1eca27d85ba3ff9d38b7756d7e95b66f6b4ac445a387968bd45005f63c5056a018ba28530adf79c0f57a07983bc865b981f2a640e2520f5fdbafd8e147687e7b52ab1a2fe3ee86703ffd2c4359ef4274aae8defc08f13ac984b50f8eac0112bbdbf6481143fe4222140e7488e19b937617b68514f94c6af8e23a0ca161007baf6f2b7f905cdc89b4bc9e858112eade69a825919bb94f3d62cd00f599c5ffcc6af3023355272d2f89a1f849d76446397a672cc8ae7614b8b6ce246d09858308c92e970aeedbb1bf76d454cbee11bb916497fd1af193d21e7777274d2d61eceeea8b543c2394e5c8685af994d527a7f156421aa6b9f5dde5de1cd1d2be2acb5cd60fd04c580ee3efa13a7730d4d1aa939dbc3f3c8e91ca3a98155fcba960a92bd32281c2a20699245c64a9a7ff07d02ecca5bc13dde0de50fb440f3f9ef066ba458da231d680f5dec5ffe2322ebc9d8b624f93a4bc55000e318ea058ff97901bf4a1a3970ca9278f4404fb1b4148c4742b78a869bf045fab04552b88740969d6c2eebf0b4408216ff2f6ed2276e10c3f0c86ac321f80ff491b41b64710bf6959e57a45f3434e771e72011fa73e82246204e28e2fa090cfca50bd3125860fdb08246b542a4e22423633608fb56732ebdb5cbe7e0685b0e46dc0f2e22d90716426157e5258d4896f5b6241cdf73dedf472584fcede9887e81ecd5b47534720e4de2829996276033bbd6be864f93796e5a1a7893765f3140b30b65c7c1001abfe2832989ea7c3a454e8f8f05779dddda4966927c6191231421328949e127ac48fcd1d65b4d00dbf61007ba9e8508ed4e42b05f85b2ade88b1b8708a0eac356f58eb660a57c33528c1eb1202e3ef77d0cc1ae5e5fa751c8eb6acdac63fced5aaba252b15dee8a78645378202b690df8cfb5f8f3d5909503056b5c9177dfdf454c5890295abef08786cbb2842cc6ec0ee948f3206a652ad03e736b7f36996fb9bb6e904a66827626dd159a56a310c52f631b251ce8732db7fa9ef210b5119b3d0be995278199d88f60a3e7bfdc5448a5dcea4874a3e7cca4e30e12f88c1f33019b48b275c529a79c6c3c5060752e37e3469d1c62422d27a19deceb0f09bef08c58f816effef34bc8b2259ef16c8c4320e8770184c67878857b507d3b68e28774658fb7fc29116bd1e563b8e998e62d1103b4cec2e5d05f5fa383d888898641032d6ca3c51f72edc757b0e3905c36f200f4328c584d42d9c278b08e6513d73bd1413d24a0da913f0683459f67c880e7009ecc58b83712acff34fc655d8b447f7cc552644558b9771f205c6f14281d4ebbf088646fb0a8b8880d28ff9f80b41a8df261d55df4c317e93479a2b08ee8a06af152203fc99201839915d7032a03b29403043e65e0b5cf08937d99d8003b78d6367fd16f06f24b7ac6ee3f48ac489b76643978271a86dabb77c6c67fb555979197abca7cbc766792073457f20ebd1feeffd7f8a3ef217d3098ce9a2c4ca6f91b9a4685e22b5419e6caf033888e64cf6d2adcb02a9f7b1a4c9bd3742b46ecbdd32cb7a37061e11e2ec740834d00dea21fc59b2500bae4e51b00de7821902a917aa2acd37f59ea4e4a58a7996c27ffdf1955b9c71bbd83f8d5743de05f75c237a13851f9becb0dff1fb226ac4f3355a89faf79e73272948850a825ac090d61c576b727901f3c24338ba013ef3f562f3aa4fb6d4bf4bc164aef6a37caccb3b07d63524741703e82834860bd129ace09ef6809f2378a87ebda310bd2c2d56097bed5e75c60e06dd6487de90cd6fdabdfaa04c0e06c6bd45048c31fae645799e43377aaa0ebdeb77910ddc919f2ee3e3f13558b110a22b84a7fc77fec2affe81db4483b242ed515f804789eabb7cf1afde5a22dd63b79b339132595cde7c4402c6964ca777a4ddd3118cb1ad0567c1a08f5f4f2f67023fd2c3f2099ca50b60d5827d4d84821373271783b5619de60ca8bc4d8e69a8be5d3d0099d19fdbc20902a7576a501f2ec9766a3ce72d1af6ff0db3a18c282b5b4f268358a06008ddcebc0887350c6a43dbbc07f3d7d23fbe2b1604165f60c885f77c2339b3cd8eda11e2443ba5dc790a9d0f204c5924077100698a582e2d4470b474a3b771479bbca3a8317d655aa742c2e51e8572184e3140c4a98b64fd9ae1f00ad3b33490fe0092833e8aab9a2a6cef22f4570836f39037f616bb31c17d51707b13eaaaad39e63199aeebaf77b39614391c76268e899027e10b9bce003b5795ee89dd6f102056981004a0264577864715442dc712a6c9855c2e4f25ee59d3dae5e903436baa0cf170c963d9c8ba359e26385de615ac6c88f189f24b86269b5fbd8ce8d7dde66c6ee3de69cc9adf55d79b544e0e1d7154acda681ab5fcbde7c1b2c5247cd06c174544ddcac61bbfa43ddf469c523e900e4bb76fd5c5358b78ba8d786c32ace47c353f66dd5dc0459ba912ff1c659d15fd35dcc738c0a487d0ebc96bd890bf7023670ad56e0ce082e4f192273cccdee4097b8ca9a405b23c4fa6c7614b594778c8374b998494e37cfa8626e7a2fe26cde4e6ca9a375117176b795406ba01de08cf9cbdb96f4f825b843d30a9b3ee49372b42ac6c6f00c0a7ef760a8ad6437e789c1eaaf924e5e0135e7ddaf477ec7e2826aa7d58d0589b15aacfd17db6a9d1caac27a684f06c9dc7c31baffa8b2f98096814bc381d2dce1cc3d1db5afe02e43ed2fbaf6c1f9f03c5936681da066197c12315e6ae39bb2062e26f88ac2a47ae578a675986db8be4c75dc74b46354e5090696f8529a10595fe8be55e93b8d5d8a15a2a084b98efe05c7773918f6fbd753b057d60fdd55795f97e99d073f1f160ef00ca0ba44386d2b3237c1476a05a233f046085ba0db4b85b8fad248197607bfc309e123c9dcfd98483f1e79709be727f294feb2424c1eb5f3a2733b8ff07d8dde0832cd672da1c26abfb6f30d6190e26d1e995a94314be69e10bc7755debad7272af3d3eadafc969fb2bd05d929f58ffde6af686baf0bbc19ac70979254dea0cb7f33b732bad38de402a0eb55e094d15687be601f81f91c30d85ea8e909097cb07bae067ce08b44424d4af623abe97c9e1f9bfab5c045db5a01431ef4b1858bc0ddac9c297d59d1a35bbece0adb7834f934677206e7b80cd0518b540c5a2d7bac0fe919cf8af5e75133b950afd74cd4693461f936c80755d928c6179a10e2f49f64d08b26ac397a517b7e3ac872058b944de963f77c8f76ae3d1bf7fb7d5317390e4efd6978765b7d9cdbd440c3b72f746d6199cc69fb560420b273f71da931c0257247e9cc9e149289af96982ee9342b2a3af365f25d1301326b707c51c42f374ebac2baa22bf1fe7f6a2ab58e8fd1f919bed31694f27ddd5d05f15af86a66987ad43170dbb8d0ae16a9ba69c3d66a3661e22d04bbb005cd954baceb409e1546792a94c2061fdecca24ba84825be50f0b66c3e7b208245b58413c0accfdf11c932c1486e6c3ffd32a40fda28cd432015dc5f88e223a003e9da6fc3b4ab2e8e4fd673d012fc8574f91f61a3b2f1a3e1a44e97b059d615b6675c9d348ce9a2f60e2aadaa85f8e8e9eb932b9132d98730aae2105d7c582150464de42cd124d18e4b1d00dbe2d7b37e7481a0da06175e06dae95d2453b7f212f1ef4d39e788e9cd793870fdc8e1dc92a629e28310bb17671864f2685758b395ef59daaddf9166ae26a6b5ddbff5cf9d143595fb15eda80410806ef84473879724a47a98cb26ac2204d82374a14434593f891836b36508df8d33a451ca58bccbedf623cb6e1278c9ef87a7a059c72e1788c93ab5638b6fdd191a4fe24c2ae4b1c4478450fc3918783b722b5b635f5e62c181d104d7c6b24909e3dae64c0459117169a863ee5ac339d36704c3e1ba89f382f5a1862c216743656a4ba2991aff465d45c8491a9197f896c3b1bd9e983a26101e731774419a88f708d9850ae51bb873da89d90b3516ae8253d57f5e52c90849fd43daef8e22813aeccd2e3deda9c1f26e6bf9fe9ca71909b5b497295dd533cf5860f60b658d86d1d161ee433a78bfeafda9a0288825c67f5c114a24039ee9e75c02c1647eb1b5c8d55fb6da6a7a925c0cfa5c8cac6c6af9ee497f3d2d55f88fb65e06b9da1683667b2406accc3c0fcd661db01751b5dc9b9d02ea5243c263119b0c1da03c36d98dbb42f104f71c5526124573f63c4df07f50a813e12c33a255c1b3e79987606d79af390ac6ab48addcee62a89cf66192d09631c34892ee44251e1189c75ac6b4daeb9d5c7671733fd52a99ca0ea0b89dbbdd6125e250c0d8c5b777b7eb51a9547ef7c3d83060fdcb5939a510dd9299ee48c95044eca09588fa445372355ed14bd84311219448b3d8f575c94c3d9d91617effc0c23089a571257439f0bd51c73e2ae5f635ff7ae3b9446416612a614992c718bde4596806b75109109a1731e1ec416c6992a520622de9e14e756cb1cb5b4e98155994892045a462619d9a9f6e3ae4e2c506ebdb5eaec68a7927a72ed27bbd2b84281e00b12528855664793f41ee75fe1424d3fce2c3be4323c35fa1a76c546cafeee4863c5d59e2d45a707a3127588d0ed59eda47841865f87ecc6bef0af952de32c5f6f68f0c9ae3dd78eb0bb9662844444dec84ba295be742062ec1f602332022e2e77ff0d214caa4ffe3548944b83a7310cc882e360b110e7a76167d6a41ad356ff68f62c7912b1540d2cd35142518f5bb0b66aada4fdd524cb056db7fda0ea3e2b86139942993e6a8b01733c0f81f91a863c9da4e98830dc12eee9c19bf02ac8771668e56bf3d6de66bb8381a90c913e9797ecc444a554a2dbffdc34f01db79af40f2d81318dab7f3c7bf1965167333f62c63b8ba9ec61fda4c32c0f13eb8a1ac97e99d2bc65d4a44cb23e9251592136a2d451b1584da900dfafe68ad462c0b993fb907a68938033216b8afd2f17a1d26619cdbaf1187e64fe46e4356e0bde03c8ca6ae4cc1697723f1c199d367e588010dbdd34ad702c0dff21595fe71208fddc30d0752a425a1d95844e6ebb26ec85e648eff348393ea6308730b472974191fb78dfe2cb43edfcc6f2fc6e67f2521c917d9921811f702855e8ac85a4ccbb5ecc59b6394ac2148147a5a6c6c44e56adee6a1d11f3d607eceb235a58a6e44ccbca793ec354172d8b22cad3efcfde87ee14c5fc42e8702071ae9098e8c59967470600fd2a5e96a714fca8dd4f0a8ac7d7bd1bf1260f706d3d08296e2873d579052598e89ff2fb5cef1576012ae6697956e27e6209b9aa2921d03b42cbfd3adf120dd7dced9731bb8bb36bb58cf89b4c5819359716a2305e01489e573ee97d9da1bf28f8d3ab7c6288c843e2c5b2633e4b7b4416c41671e1c4c0bf96127395b88bb0bcd71021f233e40e7e689496c640b12a038e3b61eedad9ae7635bbd6447ae4eeec9a25ccaf7a203939d635807dc879dd0f2fab64a3000dee7dccfd2397e4450bccc2ead97a4dcd4d44127a267fbad574a6db0005ffd12da57fe4166bfe4d35bc95c3d4318bb5506711174bbdb80ea8fff2f3c416cdbdfc3e0d3554345569fee25ce55208940372b68c8dd990e54938b94cfd1383f3e6ccfcd2dcac807516d74d72417f78f2f2ab8f27b2f6a6293f12d8967338ad8a9abd8e5a227c74a61601f9c25d562169a0d8ab90622d2d69ac03a8bdded7ad09fc3368c02388eef90c4706e68063e4911f391aea74c980bb6a51c3cd4129f0fc32ec1560838dd9256633c29895c84f00e07e6007729758a16e90a58ae1707eb374016c4060e3603a64a659cdda4eb416d66e70f75b5d453f16d6e4f822a93687f4bd5a1f5899ceb4efe7b558180b2809a8cf39d8f365adf6938cd65a00e742292233375d6c68198ea03d5e810e5c706305fbdd47f8e3eddf6422abe130d9a2165028958c1278deda56aa9b0eb84e6fc5a775daef91a9aac09e9f1650056741d9b51366cbb0bf8282dccf4f7570f40a3f465f964d3dd9ac7ea2695a86bff7d6781d1debec4f71561b5af59a8e54e018c45668b5b09bce665b541d9daa5c028c5150e96004386ad3bb672d7679c6013a58239f1977a23cf82d3d2bf8b38551e6b31182baa46c3d86c02b1dc2397df88668c93d35f7e141718ceddb704a12eb280d34a9438ce02f316a20581ff20c17f6adcd2ff3127097614995575bd0f56b61342e3ea7ca2ee1ce3861a8428e5af8f5081a6d2fb6a7ad7b902226c75ced2e18cddee3d16dbac46ece06b727c9c4f57541ffae017fe98c527d8ea25e76b11bf3d0244c9e989e2d9f1487ffb6b06faed243bb7da672856e636a0680f956999d6784a62d50f635be493e6090f24e2479ad990571507c97a257e63bc675befb32d5da333783a6bbad07c545e469d7d71d6865d905bd34ca92ca4cd692fc99d7367aab0107933fe71afe059b36816622447c67dbd24eb3496d2210e593d7a6112cad2c5f240aced736109931d259357ad91d8d85a691c032971fddf454e70448875206a3bc321f3d65d2a4058680153685e1158298798d0755ab4a991ca225518fc4bc8cccda8a0ac2759280939b6a71202e78f2548291c301fe97936d7776e9c77ee3180d1ae1d9db26d35f0de35a5330991f1c67a49d96ffbda816d97d8877d1bd695db00c3546477c1f8124a592a2997da1cdfcc8d1162fb5d6b7298f7f47441e689a113ca231cbe8561898bd7ad7d0ac1206e811ec5aa7346c7a847e4f906c5b0c354d36564cf65f699ecfc45ff9be5493ea37909519d2d0d0dabd0600ed34bc8227cde2d2692bcfdfad32da5dcdaea77678cdab663784eb2997ba9b9936a5abb62f4b980fffc34055cd8fe659e4878e5b00c4e168f4f1bf6398d2d53228e9d8a03d9c3062d6adb90e9eb8f652e089401c0e05008f1b37e259e601adc267e9b61e2ed83162b3c32f49bb5e4d580e2ba9fb83627d4b8136c2d2320d41888e21db2b57e520063b6823bce7aa9312f120ded0a9d860939a7d911fb833a8b6dc0608ab711c9e35edae7f0662159ec8e3594cfc769c59c65ff7c0c9bc29f6287b3f3b100073fa02051f64948244c2662b2124bf181c12f7bacb7729c610889cf5119dd1b967a22da09e6733a0c07a9a1d294dcee5015285cff22de58fa992ea9125f7f7d2a49ff103679ac3efc3333913dff94a3963e92983446a3ad126d9cf199686b5e2a572580627d78a94f184563178daeed94e21945789e4599eee4e62d7d7088105ab44b52fb6ca528e39ecd3fa7128b2ee9791907ce26df56f54a0f02a19eab9c0037758aca9f23607823c13a8fa2454311481d2efc4eeaed02656064ca66e1ff48bf79b0add93d741a3c98dbea2d0e299705b6b9c7063d675ff046ed96caa545c69f76e2769a0abc30c61c10ceb932d761ad754db0e88edf2846ff2bd33200ba14ff644fa2d2a6667f583d4225a8a37bc5899c5d86e88786b2014fc0f50bd9a5eae1163c8f2fcb4e6f1968620e0e4512ca4b33b84ca6da636a796de851070c8f92c9d0e7fb09d3e444a6b8a464168d1277e45d3eb03e283ac9a7cf9af0bc42e93feb3da5f746a3ae0278b5e5df6c812e97f3078606f36e3f1e4042b0e8cee8ee249ec90a93de5983f9892475ddbe668a2b0f2dec65b34099c1cedcb364ce78e2d7efed9165efd1bcad5dd3e190d6a199870742f20668fb8e799d043ae49289a6fbd042f6efd8c1c735562fa60688973bdd2abe52265eb4007b202b0366f7a86f2aa0cfd1bd6ce518681a95f69f44a048900ad4043a1d7e2693336d728461905c5b32e6e644461abcd425d58ce9cd37861c5dc4a08d82e06327444e4b229be47a7250289fcc438defdc5e6b7d72914d42ae3c7a2024df3024038be020ea35b33b1e15fd01b06a4f9e4bf0c31424ec48bf6d763dba0cbdb7d9fc35a7a7e092dc27702c14c8944c584dd8c3a87646587f247ff37490279a9f9c34a08d922913a235cbe889b0b611e4863d19a0487d241930057ee538593474616973e36247013430f7aeb5f7f354ff5e7dfc0473c8028b6219760fca7147c5cdb6dd33c1618e08872029f5576c04ca3ab618e76ab93a479682066a47a3a079b1e68edf4e079d79a65d0639ef1b4b3d3f84d66776608cdaf59ebd4070bdeff845af4bb86e353de467ec02a08515b8d5437bd9dece05429b99f87a30bd68e86041d02568ad754a40800f64aa601fd21fde4df2943df8d97eaeaaa5213b1f0856397ac28b22022511e27de0c0485851983772dcbd9ffc799abe12f2df8edd2c9dac8f61d8e9aebc97ead5302861091117fa73cbf21f7703918e3ed36e6dc76e540fd4f7b08b22f033180dcf1f63b398c9e46cf0ec66597a4d3f4002eee929c1230ff6bcaa52dbac861b00cdee62c2e1e1adf12a2f9e6770e896acc614725ce72ce8205ed24282f9ea269714f2d43c750780754bf9be6e752015ce4a2a537127b6a889bd18c92a91ac174336a6342e8a4d20e44175db43db9216df547f86d9f2ba599575bb57725a5c172fac48db01f1b68eed86c7585d4efd0132d3f85e9f98e8ff15a23210dddcc18417e62a70fad860bf024b5cb6a2784774b75a3c146a3eb1a8c7929d3cbc69d2f5e7c285b9023177b617f9c43d54ecec6e21543b3b71487f21986f472886d316a24a5786aefa6484107a7388bd8a56746fdde8923f82a1a3263ca259ca1936b9bec7f6f1cb226266459c1f2c51d58a9342a7efb7efc01c7092fbc78a254803223e18a31018d33c69cc6a79652576d833242958f46e312bfbb97dcd1204d07b07c3384cf3d2d675f6acb5518c90a88dee145c6083a9d77a4f895763a5b2a9ac04101e8254d76b07453df781c45d0d5f4085146f635deb950ce3adee734dbd2064ef5b12aee30b948f2e7286fa20020c5801e841bbd5e6025ef55fb4069b2ae96097c9b18b1a3a68c6283b3c736fc96861b7bfd3e26cba71d4e81feba5f6920b48779c4a8e68e452cd6261682176acf177addff33b5111ce3b97757892751480f76c87b13d1e899e2630c18f038a932692ce79504ce10963fd66a29356196187641511f71fe025956c603759b8ed092bcfc21a67f19a2d36add048cc056b217d4d79a53b5ed622ef837b346af08f494b26fd51e8dbf0b1fab2dcbb76a637b42a4752196b67ce99f5e141dfa90225061db83d4c26e1211c7eeb66ab0a37c101ac5271198285cb32fe71e33f35b7070a37c41cea016cb8c8a933bc5d568cb25d0a5123d0b317d554672576d12f80fc9b3111158d50f13ae595aefab29795d7b9466a0922dca5b172a3581a7a3c17dfba447938fe6df63c57082fe151745306f398a657cd9604c84346899fb3f2f8751d52935e3b27f4ab325c5ca64d31ff1e40d98bbfcfe0a2fa933a345a0843bc8c1fa44f2712b7c3d89e11695769025da5cf5160551f8773690a415a2397519c042303394892ba30a72cbe5ed0b254c7814d018d3b857c27eb50aad6800ffca3e7688aed0bcafd5d888a5ea983dbcacbf7ea41b5513e77e9545f39c1aa1c6ca065dec8dfb730bdf801b71615f8327c13772d859f91e6c0d630daa3ae6a9d55513c2febf76f5307d7921fe82e9abb9c053d59fc06b1a99d368fc86b0b7ff53f9d7ca841d5a69f3e61ceab1669dd2a7595a1083163ac69c1d644a36f009bf80ea243d9527f92d70500aff6b0751e5f8068ae8843a9a79851442307d396e3ce98312f9dd5969c0d20baae956fd7582b188f6cd7a832fc7d4b361c5ea0171c9fa52e39513f07a010c3c08080d2fc61b24a99fcc4b4d1aed608c3fadf6420d1f167912b038058a4ea19333daff3cf2be62904ea25c2843beb5489a58e19f1efecf823682fc4e4bf22e8cd8dcd36fc5dc02f1e94e329d9b5338ea8c3b909ec6e5dc87c74ca0aea834a9d96738099bf7cd8063b650d57f23f15498c783de844de2cadbe6bf1e8b71e7939d6d0f7be2283af91358c9f926336c649d1\n");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSphincsRandomSigSHA2WithContext()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")));

        sig.setParameter(new ContextParameterSpec(Strings.toByteArray("Hello, world!")));

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        AlgorithmParameters sp = sig.getParameters();

        ContextParameterSpec sspec = sp.getParameterSpec(ContextParameterSpec.class);

        assertTrue(Arrays.areEqual(Strings.toByteArray("Hello, world!"), sspec.getContext()));
        
        byte[] expected = Hex.decode("f1559e4e1487a12d25c3925fb686b5d3ef4a1c5ea6e8f521b80c386fa64b7d269af3a3db0f320573fb83780ec5be1131072f84d87790dee5e1222f2d3423fff53d572f722d4903e60c611dc146271472da505bd67b1d25d46da89d70f36993ed9f4577f0d35ed5d01487161731ab5683c21bcac805085afb70d3d89296b83cd43b43d8f32cc59ae149c036e8872ee2e1f9cbbcedb484077784ac5da2939a6ec13f1018e0cc3e8f9056e1e8854c17eb766ce779577d2f48e621eb5597e86e92025df55273a26b3f3ccd1d01e0f73a90618b572f683947f16443a50caf79e27d06af57ed3eac838e89122895a63e8e95d58417989d4bcb4b9e582a61863536708da75730aa866ed349b6b653c4db3e5759e83f753c4cef2d6e98f4d576d5dcbf4db1e8efb6b6516cea3f8bdab41bfe1ebca6175afc0daeb13a66e08b1db9fce01c064279fa00d1a25de78d2270cda5a4c8adbd32c0e13f51f34909269d08f464a75f6f7b2d7ea3ee28e77c299511029e42f138cd035d65a85427fa1a41591b1b2e2dcb706adadd07bafc3a3c121a8258dc813e4ec79e09099fc73820c3d74a287d7084b91f70b6b71303f766bec82f42a26017230d640e25f4f58cf7a53ea32a62595966481360b792e7d65edb023b5d2cb1690fd2db6761ece28bc5fbf6a4320ffe2518880adfb42093e89c04d165a08128e4dafe748d6b2cf7c49922cfe2fead253a27be2a41b64e6031a41b4edbff8bb41b5ea0fda954bacf4cd762c7b24559fa1c937ff15b1538f11fb2c59e7de35be8864f84619a9a860e8d612b5e98d8eb33414bf215ce56a7a461611df4879f0d076b8f3804a2f0b4bc74552535eda817869086f5e32cd6681670850a9237c62a29e5f57ee1410029c3560c283015763c3ff514afc922a16e459d37e1b13636586e91026f755ce892a1af3f4e5f80bbcd6de89b0eabe566ceefa91f152f67b2a4f4d3bbd196f5843cbfaa3a70ba62ff133534844c7169c0adf4ee182ff0bae90035b1b177e76412f61fd5b91f72b1b86d2a9f65ee6d5b717a3d60f9040c65187fc56c55bc1c21de4b8581310c49646d581417a3960e90595ca836f9f3a2acbe6a1c1fb109fc03a1e881ca865c71e0dc39798169fe9e9e730e782d6802ea603abf07e97e20e7598be7d7d826ec8593dd111eed6313f03209dc22bb4152a96221848f23c8c50c839d9ab92e3187b18a06a5a76576a922e2aca6bb2b9b87ca7c0655f021f4d57f08303e075ab0044a7833e8e60e45f9922302cf1b7889b4213069f3708ad3f6f98718d6ea6b2a633ff0a403e2df7165e44963bdb608676f9a723efaea87df982c4ed2f214bd416a64d9b37a35029c26f3a667e8f64149c66957b72375cc4e5195d3095b410d51d753f1af99ff0afa982d830b5acb8bdb59631f93d0cceaecdd132699fecb20d171f4eb0f5854e82f83b731ab104cbb60562a96aa4ea166dd554c04b8b815ebee3490ede49ba186e206e22190fbddd96e2c1352d3c6a005abaffb734e45be63025cbfcd6e57bd184b5798ecea43f02af942e512ed5cf09ca3519cc61476f84ec67804fef3b05441859451344b3418663babb4f56e583ea2f9ff6a146c8d18fbb411ed5bf795e916cf54c6d038a72153c7b58b883a7784f4ca1593b81a30d00a35dcde29ff4bc537764a8363b886a856caf1bd2b3f3f7b53c5dffc6e1d5686c68f154e01cdc52262cde9ad301b7e8920267a5cc478aeb7800614bf270d9486f27c38b6e36561adffb5f1433f20a642ed7a75d4f41b8879599da1d108945ee8c805434628f03fc9b88ea252c0e62e72ab2385e347a6e045ae7af2ac4bc28fdb5a802aba7153f9adfc585308a9064f0912889a8fcf645a89aa7e96c47a9100e75b6714fd811be88cefe645fb054726080210e9f13d6ad8075c86f97026550ab46a9cdde7b1573352531d0a7d0298ad22b86e5609846aa80f0a8bbe5e894864f01ddbdb52940aedf9f8389ed5c9325145201f6b2780747233ad0e6e3f790789d6a8cff350fe3904a89925b44abfa1ab68db640d939e666b628968577e1c09114b9aa37cf3497a574596a4a281fdb49621412a5414d97fb651f6c42fc7ce13d46e825a1105cfb46a1ec54d064bb0ba18d8601173ac8f42b7f2a36a10493f32053078e9a3e628dc8f6499ccd41fb004a0340930a2f53fe448bbaa8503d1ba927f8f7fb01cae80b8406d5c6703fce77dac4e7500819b74b6b48646aefe33b61ea50a7d9f401571b78cf5dac71da3d6f92d7ff97de88c793b65181e81cfd765aa43b0b8053b91ed80c94f654c8bb7372bc9fa63ae89c60e3935fa9dd54c5a36fdd18f5b835d0614563c357549dd702920e185a3a8c7aa2fd991740c98462305e463d0040ab679f5d0a4cdcc4452dbc2a20b8adf16c6d1eacce566f6d94d91d0cc8a1f794ce24972c8045722e32b4519886b30062629261a4ae01f019f8220a727f05a4b467e6585aa13becebaf0d921b76aa777da366822b1dd969ea9dbaadd4698993d9154d2b4ed48eda8050f9938e2139d96b6c6d48e9a41dc5ff990f493bb457b0329533e78868cf67b9051af3d98ed7f5a7d636ab809ac00a7504a6b0703d3213ecba5ecd005d6a9095fbc5290ff23b50a19fab1445a3d5d805290543a9891bc751fd3bbd65aab0d84f763a149825df1624002c744d413e95214c34ef7d54d392a5dc0623edbafa9b763dcea5160623c3dcb584609b1d279a39c1ef316ee622c4da5858df1cab8b8d86ebc3ecc0e855c67a41892c523d720fbdfff38bc7e0baaad7701cc1461438d8ef8bfd43be14f4c14fdb7c41a73bbc61bf3f666f1d31164fcfcae4395e6cbe049b6d81dff7ae92cfd121e203891fbaf555f1fa74a066f445bb397ed09795fc1d22bdc63ac35ea9f7b4c18fab6948c77ca1e3edcf8fbb2a39afab9ec1330bbf81671a1663cdcfc1b65795c0b3211df3a31a623b131dd6535dfd46507305bb3b8d4e0cb1e3bd498e7dc161f218ab03d3eb1c62f995f2b5518f61837cdd424b52fcaa2e31be8d496a9bafbfdc7f46f4a31df7d541d58616fbaf7d4a7e3419c23d8e95a61907d03571b251f887e2b2270e867beecaffb85f46e0f426ffdb1e8390c668ca54564227c707a8c24ee9a28f43e5eda40a54afba9255892e1d05af2015fdc9849b6c41f10ec465966c94c6d8a73781cc0063fcc2cb2ea4a5e41a6468d7d05b09e9a472e3f798dc81e10acb04f567425f4b44b6bf841a58881050b07e0b1f36d1a9eb237c9b4796a172f26fc6c055f2d80dc0d1b7772a17449ddb6337c6f0fb532457cc5ecca8a23185bb211ef14cc23914355914aa61e65685c6e9a556fb75afba3b90a567041487559bcd77c204ddbcd48c1b59adc2d9d1e80446d6fdac6305744ff4cb2606ecc1bd91e5d63c5f90632074ed92033ee8f92f5d7823a12e5cd8a72a31237370be32db8ad90d29d611475c4e7274c89a886793915808e76c84cfe7b907c1963e900f67b1dac0d3d8349a3fa86b4237cb3e8d51dbfa07d0ffe939f0b6b2ab39725b7c216a135fd157c1087275eac9e41c8ab3b3435609e23372b1687a619a9fd76240ff2793864e6a0ce4a4ca824849311690761f45ab4682752edfc5640eebb0553bf41b396d807ca1687afe6e8c5284666b3a4d17a398db1eda0a4e7c28563c05e9ba45e20ba25bbd59e78ef66c2478bfc3ebeec30ad633ede7d78d6448bd85943295107c2f38b9713b18877cf7c3a13b4fd3ff14cf18e36a74b92d3c8ff5c885bcf1e250fcbc050e49ccab442c0ee09e43fd18efb1a90d1a65bcb691a6b4c797bd9434e71289dadc0c198960b8745758481420dbb083f86471095b594bf2baac473dbd3520fe419a393d38c417b1763e36be61edd23c34330389bea0a5f3dd8640bedad13cd7725ba9cffea713bef958f980dd75a73a21eae0421815daa5d7d1d0bc30471b59aacbb1576041da32eb27adf9a36c17ae82a813168bad7370c7112c09bda51f54ce1880143534dbae1842c631b0801345bc3245c53a736a58b354b2100206fc7fb6b6b14009593123a810a1cc66f6d8c50a408cc36f75851d43eef2a60ad5b3bfbb00209aa45d943433b6e28ab97b090bfc9d248af3d830923f7a81e4019a3dc985ff398591ec542b832eb161d5c53b2f1f2608d4856c5c397d52d38cf25ad332f358a18943365fd8e0df612e66aa00624e863b124acc1d6ed692a51560a9e079b01e64952cdb298826ddb4c60df04ea18bc69b88d2b15dc6a7beaa04668cca5889b8a17fb8c0346b2fc6c89592680ee749bda1fd0877fe1abbb19549d91cf0860e81407fe98e0079872afb8c2136fb406749a47bedabe0c021d51076fc41aa6c8b4af686a8ac5bf2bfcb5f67919e3ece65dc5274e7481758afb4863d4d89c7fa87aa9a45edad2e390cfbfc84d71014307a2ac50f77bbac07b084ecae42fd4adffd2be148485f90bd9ee220f24bf2a7906d0f0959d9b7d880d98bee3ebaa605bcb7dc3896509f9529f9d562636a80eb0fd7879b8a77d4777e480fc999e13bae18059d6646918a735f5632d0c952a230362ebe56638649d554200a5f1af6e96e17b2f56872aec56afc84d9cec1f67bbee700be38c304f4ec408d6f188dec2db46b279e3de96991f9d6bb5c9f545de518f5c851e46df7774ea5774bea43e43d982dd3a30187d442bb1d9f576365fc7ecf60b0ef2e05a431e3548b998400a8617a3d0415695afb5d69a8bb4230d99df05003a835ac2a8f14129e7d0b3adf7077d3c9f0f8c08d5b6cdd05f3eb97a0e3272b776df1a5e9344232e1de24c45f60d3d40aa3033c7de7f6c2bd247099373973988ae0b25dd859adbab153149028e407afe90a755bf391ce800dc232a6e7d3fa6bab1becc0616529b23dc955367140b64b9aa9b0d0446f1215a02c3edcc86293cff3ce3d514e0334596e63c6a4d75b662c21c04a0ca4d1198b64597eb4a366560d6107722ba1261560996e049fe07ecc8d82cebe932c13c5a8b12bbb2b83a1641245853c7d10676b81de86107c42cfca912aa6c9d530abdd638fe1f81574ab14e7d0c701fe6197806f9f04fe32646720829075c765bd03f1ad51409f2930aaba51a68c5c1c6689abb6b19910163e60e2b6044af86eece9e6d1f2afa2deabb0740303d7a06988f4396809c09acce4c1179dd5c8d58ee4c8e9406faa3a33f15045766274ebb5d6413286f30d928a09c0093603f7592d528a99527c6691693343c6580207c13d06234d38854fc0ae45d56cf4cd7b90e757a6b5b448887215e96de4c00408e2abe17706642280c5a62774e988ebd4be3a0fe406e4ede30e04d1b92db9051ef9376124256f6293c4674ad14a27cf6b7603d634d7c5d3819c1c4f7517a1871b3d12a37e34babe7f11b17f3052a1e6e163aaedc243b590c502f9008d636bee4765b0f5bf2bfaf9870ed02067c58fd9318ee87a04b81844a533766523091450236a3f9c84d6fed16eec3eac21552aee3ce1ca97132076ededc0ca91f189c0b9b64c16d46b4ec60f2caac94fbf9b0d44e0f8cc55f167b7dcd2e8305286cd9e2c00cbfa514333c673c3df7d0c79fd2f7adb8c818c3d5e8cd8acf74620d4da61034b167a5bdc8552e789fe9db25393e1e613b812253a79a0fc705c2b739cbc0b774109bfdc304ac7db1ad0da9c99e2f8ad2a44712e078d3a37af231fa11b028e06afb9c6bf56bf754f0ca0ac9ba9d7aaedc96664278ba2cdc446712a497b305e7db9bb68a22ccfe167c16d55a5e5ba9571a810445b568cf55820b51c7c45869601dfcfba86e2be78e865a97d635cde561909d3175b2855d3d7ddb705e51b196b23d34e7536ad1af68f01e61bb83f9001cfa18d1e58ad0f43c7508e01de737bce146b918e4d5a2130183aa80e81c0e00eb8797db6bbfa001884f8af0ff0f0cb1d802cf939f264643f12418ee9a8fb3069de9f2e110ca5287b202aa33fca024d4674b3b30d7677f6ddcb52a52749ec48e5a633c9e9025ef20c8b75b49c2e4c77a06d775553eda37125864f6f2a8c42d64f945172b713743129c263593942f313b5a6d11e25da446d80e80e96f73f82138f59d2be4a916d7cdfde85f78609df8221ebe9a8bf9a09135a7864da88063faa7e37d7fc800a4b54f1c217494ea2aaaec0039668e61bfe4bdee1874504d7ac986ca944c46620517579f829c8bf5fa79019037e2123e83388aafa64e2b1fcd7724fd86dcc7782dfe44658e34501567590a9a414f07949f20469937b1ac976e1531c18909f0ebfffc1b030ff16e35df95fdab0628bc94867e60bd38d4830953e5741967e8f3e37d9bee925a6d9aa3debf3754182b78ff2c214ab188db73e65ce23479f2102df754e5ebb52df864241de1dfa02cffc74ae9c12f7457da40fe55001b987cd1442378b9c95149dfb552d31c7761450fe06df4fba4532af89b60d73dad6c0cc0a986cd19f5295f9e132fcee2c753927316e92fb4025d3b7f19608ad41eb1fcdcd90ad969c026ab0c122d96b05a1d379d2eba859dae44a800d2832973cb597f064f7a20e27621865999ae6c95b6e1d3e93222d02bfbbef528626cdc47b17dccb110f4afc11e3234ad3caca0df4819661b4e6391d9eb2bfd712c40ea8ed4b58c63518fb39de29cbeaa5a6dd00b5a71b01b7801680a8b9724050be3f3e5224c0fc094a485aac3df84deb8458169966c477e5229efe950f78824f2e7a2104ab4d4343c51186e014f2c595b81a8b22abec62d54264d0f912cd6098551e5fa37e20b8eca99bc93789c2d5ae98899a32cd1607f4afc41853c368e1a92e5617dabe22bb75750dccdb87260dd6cc951bf3b308ecefcb9fdc9e2e935d417645dad4b9605c9da6bc7b6a0857a44cf130e9efe2c1c1f8b3ea57e5b9f62aea3b0141387b74212077869f745064e1328bcb1716d4daead60b98cdc690efd31738520ee5f140610032478d93ba584119a543d086a87491fc339c7e50ef60ad1e6e6d7306c5530ca114e5c8b3ddb96ef8bd67348d67538617414938fecf12041a719ad10f2b452837649dc723e80f686d7b31477b191918c02cefcb7173621b03cee14fc6afc4282e39d15dee8f3b94aa93898c6f19a053542860f00f70fd77007b7b7f5209a4ce8f01f19faf37265ab892b664bf1bd9704537958def07cf6f149951f94deb86df41583b7d98c79ac06f69a6d08c199a01293281f6a74c4ee716d66eba129f319d03ca381154a58522df667bba8d1269b67a3a3d30172e32a7af73fc2f7000121792b3fcb04a6ca12d066110f669dfad28aa01d8024762ae2618aee5a3bb7e273d018f5d1de43c40f0c64222f8bf82b8553eac91087d3a3baf3499e8515ed9e4a1ac07f7377233b6d4a868b96c2ac08df09808d07343322a8afc11428bb8aa83da2306702909702720983bb622f3f2a441630083690fa5f773a80d0136d75651f8dc8255fdad7d6405ec4a9fe73fe7fc23f0e40400f099b77e46e4c44809d73fea735784b4d425a1a05a82bef50b2bf1a1014df39a5aae7b92ca2b01ac5e6f1fd29f446e7a0f1d43355209702aaf2053009d86d9800471a4aa351c9047a13fc4d961e8e4ca5ed98004f1e58d55d35137954b0ba8103ff29e94615863f351f103b4da353db1227ecf69cb269a436425738841a975b80aebabe6d58e219962fca5c226e0936d73d5605fad9f110020f06643dd625a80f23d990471a7501838e0316ed81bf5a501acf8fdb5605356f02b51ef0cffcb46402efdb274645ec0ccf6146d21df5ff73a8fcda3e32ca1f58a8d3583392cae5bdd882075bacae4b5e4846f9c18472c22fe2b9a3ca1605d23da99ea4af9ed9cdd4aa7d345ea504c7237bbfad4b0960c68a5e1c01b983804dbc18b4041e60b4c07413303547a51bbef09bd4562d0a62ed7467f7d2cfa676b0d1bfd8da22d3c4cca5c557473fa960e19688b8328db25fb454cd489f0240ae9ac28202765f9f5b5081fd39346d4b93598d1b7c18604c10250637679e90488800acc2f11b4c26c9a2febeae60cdeff43f483f7aa0fb71f2139d3ed8acdea4cde8b2b6001d3b89b0b491d0615c0616adcace408b8c118ab839e0c3d315c4a9274e639861edf0e86600fb44904ec1090c45434a134d1c803b97bdf85aed678252f1275ce931a3b180ea0faf4655e7a94f5ebba21bd6e464c9ccee598549c71733ba1e2d1ff80f646d027b66c92c72fb3d7ea0698b34ae16b39bf0368990bb1655e6d4e4575835a2bb658bfdac0cea3df760edca4c10442bb093c93c422083f3d05f2d865ed32b83aec37eadd73ebe9e33280dec41908f57e293bbc3ea33747a64438915fc647a3bed7b473876899fdbd697a83a37a1a5c9a8940ecfad79da2dcd16b1ed3e0b8a8cc7772e506ef00417874faace4da4681cd0fcca8700cbcf1c9892fb8bbd73887ef5f99e3fdf8d8df60999836f9f875190a19f706cf6cd4c3752addcb39483dd0f89d968e4fbba6aa20a5c7a018124fea8042c749c617a34b2812edf5a4b1d1746650cf114d2e99c30c930f040ed015b4b4dc4985e87b8cb9f8e8736a5f789f75a824961d160260e5c1080997c7943506a3989825f665b1c21de41c17f52d16ac975a38d687d6a139a3e21b91c83eb160a88285a02e67ba4d3ce59e1ce664fe327636f30e2782b27d2cb48ee4de9154d6dc73504d7bb209d836ac410a08d032552cef4435be26dd5081a55fefa01d93bfdc214fb1dd36c9ffe6c02f81d53a51b59002451c69374b38d2857fec602a2d43c253450ad32ec520f438351ee4696209493623d3b374ea24f165a6cc42096333b895bc004250a5aa693a555dc65cffaaa313115c0d6bb90e864b0b94dde42b08b68fb803f5fa2048ab096a29f6823a62c9e322e5dc0138ca1198bf1ee0a961733b0d6820d86b015084ee62703443435ea28609c803ab6a8a63bdeec264ac1593bd489209aa8ec11f7b53eb3e27325229e8dc0fd0f26b636a1fdbdd0e014555855f79988caab28b06120dd875fb62a84f65f324f02461f36ebc0d2afe8855851149a1bc7d6fcc9cb2f12ebdc6557a106faa9b7d808da76f724c05abe47e0ab931019665f1e78cd7ea2746badc1763c73d0c0ecaffaa886d46b367de3eb25e716e089ca90833c64860b70c020d786693f1874f8e20f5bcbb2d0da9767751dc443d1bed1a187ab0091b4935203c23535c5863ccaca15362ef149d32a12fa22ca99af117e61f785d6c05d358fa27b6a7597b446a64f1fec2e7311fd2161d33d5011b6cac38684e2df82a3d2f15eb7e79b24ff60320b799720022a8ae1d89bb9c79d4733966b61fda4685efb06711e49c14471f6c33dc4259e654a8a766fe3e84fa41270dbe1415739555c720e41717de123a9f85febcc802c0e47e38d090186a8972f2de5c73d3f3bd12fe5885054a089e5c4d448a35a56ae7ca13696df44c1acaf9a48e043ca6e33c32a974f296bf7ebd75236df7e3c7248a0bd776f8da07be6dc4d26f962a3c4d6a8f0944c7c2a1d2d6e3f03b45ff2b65871de876a4d3d373987294fbb078fb91fa915d91452a255a9fc3e231ea39598c03576f42afe53502961e14c58a462bdb4649b1ae31d068378d57f0d0c048a0cab1c4cba2d2e9e244eb98ae8e694509a0f0bfbaa5fdaca43de00e41ab7e561df3c7e367960b6c918bf75631a27e186161d0116d713d41f41120e5786507e2e607e40551b70c294254effb226d51ad7bf01a2e6f1f4948b2aec4f1c0baf9b6c2cf567664d05e2973e76838a3dfbf5cf6d591361cb46e5b9929649788470a3b6ba3f0d6dd7729be07ff24c907acf6cd1cda0ef386121ba7486ae1fabe1d916a5f247c96cb9cfcb8c230cb87fe9d8571e3dfed32b8706f24c0b3ec61113c17f194d2ae485ec9249eda99f19749a9241f2654f43266f67e85913e96b6078fbe7ec49913f180f58c34112863bf17f915aa7603a8c09aa081a26ef72cd693d27673a46d2ef34a974c52e44231479b0450aaa920b3bbf683417981e5f3b8a48ae7abf82373ffbb601527472cdeaca5adc2aae628510843dfdc14253ce16d98ac6048fcd9acd9c75d0f9864c7a08ec29b76934ffa110d470c387a1e5d2797cb9b1232b455eb8f47f84337216aedc961cb55cc4672bc509f7e7fefdf6110e498ffca5952cb66ed2a41c6a1423d424afa2e3673e7b82408bb27b37549de7d02b35b3d8c8110b99b0a90c5e3e9c49b27375719f72cec646973df2e83aff95fdb0d033702cd15f7f84a4c4abd9719425714de5c7d6e6b6fe9e3d146c7b3dc778f1d38c18518ab0025e5f5e754f3b05bf69d6aad327155ef729d9cf2d6082a3f78c5e879f4501362fdb76072b5ce41eed6f1d4168bec842ee45fde38b048fee4bd570699da292b3e518a1913b6c0c57f2c3983342839df81610dc195c371695bd85f61b0d18588246fa5b64b922f738e0d2c0984a6340c3cd9df8367aee7a8ba8441d59e406f327ec11536611972e11b057c45378b05c4c75e0810d6def98b4dbb846c77b3e01f581e67f78e3f5810cbfae071a79aaa9b12a4ec50383647aa27bb2813462a5db426cb0323c80f0e1800e5db2d8af718ea934338fede0c59e14341da9146b2b2704ce7361a28599322b93e8a87c0f82cc2540d539e4cc043b29a1c2fecda6132cc26d810cfdd5293a120864a4542095e912517a5291d6d326c2d10801de17431e5ebe0725a5fae840c97ab76479fd3face97a4de7c18bf0a44f8e445ef308990db6a15250e1da784cf362c9c88fe1fa96120b48358ddeda30693d4f16dbbe02f6c8975c7e557b3d5dbcff0f03b594abf5446e5820ebf2477bb745ba896bf0fdb7afa580578cc092bd23e6c0d2a830c1f98210f5a5739c05df1a7d2b101f45b9df8b72344f0861cb5ef1d0adecfbc904b6f5b6eccef78bfdc4e9b177453e53cd7149a51bd1129d39de1efc965fef5783dfe14d288864577040ff0a08f22f214798220aa7778c586b19d3ea26627a4f253ec23d6aaa6386d847c02a6e6ae17a11986a3043cf9c9e865100e2351dfa81f67c0f0f30ddf47914d76666480e790f3cc6caf0e65a5232e24df0d32742463bd9bc7b5f66916cdc39187e197f5fd62c2b5e943897662d04434eb708c5b3fc68edde7fdf1e2a6b4e641684e40608fd04402886031077aa25a6199f0f32aeaf48556632c68e4e8c60693dd885378618097834e2d5cdd4c7f318fb5a7573d5bf1cafd575bb5e88fa1c5d59655930f6883e0782a60361450daac5bb0eb80c3fbe3b9b34958f54fc39f293e69707e75ba15019e4e6158386dc4cffbd21f4406edc947391aa9edd09ff40d2704c2e5dbc12b1a9fcf32ea7a0c0ad79bb725f56f2ed9649061998d1e1e292220d56dd4eccd17e3ec6aadb8b008479ff4ef4d887957f2e5aef0a743f054e82f7ebae7ddcbb7896d3773ba4ae3d92dcc3ebe108ce4f281d6bd28fffca2ed63248f1d8073f0a4445c0ededc133c374978872c25f7de544b9d84d41659a0eac532ae687d592140a2c6dee439103482d0a51fc94742c9865b2bfb2e33f7f4b8471cee3357e290b3fb6067d9ba014f253e0566e78476c7900b66da4c0c512b11e970dce31ba84cf07fed6e5b8d446b3f32d8b48f525e214808142529b4f130f03226492611f4b45d6ca2cbde213411e204f8ffa1ca1f4367d0b4c086801f68e7101ca14a256e134ea91d8080f54e21dbc58b38933cfb1f1736059a94cdf3f520b9f9afd4bf8bd761b4d3fdf888fac90a6dd0dae30a966ff8e9d68b33ab8026c93bfedbcc718444b69907b93d2ac380d1a21886b5aae41e104d1afcc964172e37c0920a0c966efa011e4e1a70f606af1677b606e8c6cf964c22727c94108ec7132a57dcf56ae942b987188ca6f0b97ec86614218545a85798f9c40556f45aa2f80dcfc9531a9e6bf8d454f53e4322107deacbc81ffda5c27f5bcf4741939d5c84bd33e446141c1e7b4a4cbbbc9ebceb7bf27ec85d6576e14aef75f144b7b30b314a5c7627464316d6059e3e8cd0307af2855c883a5c8426f2e966c30f23926b0fb0ec610efd34235f79e68d1d74d0789142f2e6bcb7126b104c311aaaa3c717f757b0bd6dbfbdfcd21e8ede44b34c8d50dc8345aa26519d289a8f5032c4ae4b1cd20d8735a6ca5c8a5fe1941b5b78cf1cba92e26abb689bb3d8c098f37a6d5294ecd68fc39e34acad3030e2b0eb42351a10a6b0b08143f79976420df33b99344032ed6bdd757703da35ab313a39ae92184e064ee296c73219518afa2efe7bd914123df948843a6749e2f709ca6fd811921ab12902be450d1b4b554750fc91269f50265d41b360ba6b6d3a2a3612d64bb8880fd6eee6f4d92ae0f1da7eefc5dc11ee2d85832e0e7564be46c0e6db8acae3107372f72f030f4014ceec64569340c22dfbc0571ee29f3d55f407fcd5b38c0806d875037353b31e05a8d0a0851f05c4b6e29df27cc90fdfad0300f38bcf264a75f9ebe7d03cb98dfd6b2657d856b53bfb71f9fb16d2def6fd14b86008031a122927a91fa9723d9820a8d13a00234cca08daa74d8f0cbc2979a51875c36c5b69d814866656231f445a3edb627ef3790f254861827052efbcd80d01f7ea66f00005b35c3fac3db470aff702ae8c95840c4d4ce9abfc607d7c336a4b010407437e6a27cdaae4cc36ef2efe54008648f397f813685cc2b49c944b8bc2b16f07e35fe8cceff32df56c22fffa41b678aaa89aa97dfc02a753913528a1b62d7a41d2378c93fb9f5ea47a4f25336048b1dd7e070a646a497790d71e23e3f950fa548f9fd15d624cbe7440c22bf7a541593ae32fe1825ba164a8da94626628a73e9b85140412666a1419a1ca71feaf537934c0f37f4ec570cd230d5a0c3421c8965887dc55fc44401e8eae27c0b50e498cebaaf3bfc70cb897813860cd958034506cc1a5c87d7b86a994aaf52f9059317762998b290d93fd0fbf83e2722fd1cf482efadcab0b9d64b6ad9dadfd9b40eabd4186bb9486a5711034b357fa85f503ec5ecc43c5473e115168f8bf751734b3108b5f262273f12536870a0181fa4dde486e60d29040f0644f4f0819d976440d90f46df6799818b6fb4cb8bdaa2c281869e385de59817eec2c2c6749d7a500d0ae93115e4c65c0641f4146c0db9857b2874f5f4a6ec11f426f6d9da69890fead09cac9d760403f3844449237a7958d60eb7ea30548160461df0b2ddfe0afb6e3d41c86e20f860dcd8da73296d1f042546f0bac9ebadbabce4fdd0d7828a932ea992455c4d2c89beef60741748504835b011cebafddddd799b772116de8a25b455f1bf6d13a705f9f1a96021474ffeab8bbc66eeb20e9d4da66f796db828c941195834cdc32f08007b18d2c8971bcd93dd906ba9d3d4335a1678c733fbd450b91349285d79a2d650c90410d9384618a93bf24d662135a3f68ed179c06adea7ba03418fb720b6f8be5ba9840c1ec71db2500025d52eaf1b210189a140cf1e4fe107eb35fe7a1080db23599de1329566388ac5ae7141d0c9ac9a3f2fe4ead32008996a0a68672dd1b6cac4ff0ac9eacbdf58b1c42b3361a191ec147f1fe2a036a6f347f85fcf23bbc247ca2a1c1e81ca55fdab054835403736e22ad89a53dda396d60e1b6dd78c91f1bee81aa96f9e623d81a51744db4a0f34e72e7090f3355d4154e5d06c9c87cb191b0ed74c681de0c3a418b38340598efa8b22c8959a6d787b30acd679b6e860b58cf9b00eafa469f1d1821f7f26f2ee70767736e8effe4040f0624462dd800a760ff917beac8c32da7c27396b04c2f59e88dafe28378c99f8cc466b1a3a183ed4d26f219d8f82840375f57c03b559387e3c9369bd19e8ec24b8d79850a116ef89a3f99406938992117ff71e1c3214e1f92e40e82168d98835f0a2eea0cddbad499a5309f3a71e08e0ce1f2d1594d41674a8740599aa6c86c7aed0ffe0c890c999a3645ddd3e03b99bec7a25dd523b91bd9dac618b615a03812b493ebf79897aeb65dd7f0b0df701df149587213a87034ccc293545db67e7cc6205a5ee1a945096c8772466b440ff7ff7c276211d4b9bf8be9cab4dbd29ad7e08e7bac07e795ed47cd24782cccf703148104d14102292aee5d9c65da1e69cdf9e9b9e351494d74355be5b7109f9afc819f0c437078fdba7423e8c842a1d010d2969605c3ec3f8fcbe10ac81d798ca3689e745302017e026f6efc8581b3f1349810c81ae56ce61fa5b7802d986900165b9d7b1957fff2549c66922d3f33b38fe533ce14d2cade68c4d9a7d552c2ac8a93b2bb7fb149a33b6a647717a23ad33f6a57103aa1ba55c887c86d2e47425d7c9595db825f4faa6b3b7a582a7ea3099e0809cb0228cc97e7dfce12018c75030cd23aee56b599aecbc7965b4b9ea0171c4b8cc6a283d1048dcfe336de85f7683831a7a48133587592901eaa0291d45d5902d368a175db51b9ff464a8dd5be8e646803a6ab444ae271f0657084cbf3abacb16d41aaa0b42ca7c9339758b6b321fffd8e85c5f76a8ce4c1c700ba5f38d0082740e9825c11c4c57c36191d4321a98ac8e13f9d2df9331b5767fe94fa10fb62de3a915f8b6b23fb3e5f1bb24dc495a55a2d2757675190173d995be1024463f60f9fb6dae736533e2180d1fd39d078835fd6d139f537e3e49e09e44db887a0a188760dbc3f6dcd03dccd0cb75d6bcb7d8515e2ae0723fcab2cfd964958f3fece1caf8b73d340ef0df2901a09d659b3e46bdcfc9f20ab9d7ecaf4b1ad38758368b50a67c38cb0d5b63906b0504afc0f317ef1b93875bc7fb63c9089d1112149c614fd913a6b3b41636156eed565afdf182870f947e1de8b0262b226e291eea6fd138a8d86abbc728b01ba926bfeb2242a16f6e4d8a5602b186aca54d9303b04c7122ce357dd3996d70209ddf8b7e29ac5cf7f6049645ba3f0543c5ea53023d108db18636ca7e1b4dab86c23ca652fd7f99d3414249f31bc180f5e7bcc0b1c00ef09c712671fd9a3f22a286da3279f36832cf211e1e43bef42ffa31bb1edda44d1b18bec2b8e3d74843bfca12ba16f08cbe0f89d8dd2f41965dbb98f5382cb1866239ab8903003463030f326cc03955ac68f0c681f1dd6831eb74b9d2e5f457fcf7e999f7312169a722c0a4d4376ba7a39aa30a68ea2f65ed5ce4e8cdeddfd4e97c3fb04ae76a62f286160df46ca9b6f02a1a66e9eec9201324b585fd6621cf809f6ce81476cabf37af095e17e9487ff197776e49944f7e5ee6813d8cd50cb73a6ecd6c5ed076aeb29156d9ddac15268144fd8bf235b895ce29cdab207c5de539604d06a7409524628e641fe4a3cd2ab2d7d7160ddcfd910b39c114cdddb942ccef7eb49903b94d0766355cdee0503c8b3f9f258639c6778d35a931170393f97fb4b12723e006e5262de3ca275df5e0add73e0abc4a408bdc287a3c380ca9dc0a86fc9020cbc1922c7e75269e5ff52e6e0c62eb9a3cf2135d74f57c8a17e5089f99be0359388f733a75353e60cf214034f8c8af3af5d0fc8f3b361b344c559d12e6d5cfb4a562eaad6afd6fa41bd5b7ea614486b3ab69c298f1637b923e2b2b47991ec2753493d6e6b6b818d05c7d3e539226979604b58b65d5a2a86bc407eb700e22697c9aad677b0497c49aed6390470855300137dd16d2f17737478eeab2a0b4da2c41776e2c3a9e95de0cc89ac9fff2de0125642999d2885241d26bb89267cee7eefe50fa8565a6b7963c479a34b7b190f7d575a6fab03b1a8638ff77d23d1188e8a6763f872a651aad715bbb7f4d7ef1ed9517e2c65e8bbf803b221f4118e38340d80a99cc0158527fbac3c394dfc9dc7a983fb12464a81cd126f2ebff3c3c21d22eb3f000719568d7c3d4ec1d6c7754cca8703d5cf3dd12392e154a7a39c709867e278db8537205e0249ce2da0a11a2ad5e94a3bceb1e2ca7970ab0a02008727bd43a2670927c8cfb01c16ad69fd237c42486f5d24c1f2137c454a9df94257a93cd680301fa78ab6c1ace88ebce8a78c01bb138d6fd77e835b0806165b9865ee6ee2cd7263e14ddf1e47ec56ef33c58e3d87ab5db3921023b56340d14b8f61a811d588734e4a572c292d6cc09a28aad5ef002333f945436001c750adccf8ec9bdf190213607ff79a1a2332ac6aca06d5e303b3bfb817ba53d7eb7f9058ddbe31748830e2803e90714e1b3605495da118d1a03f983cc7424c0997857782362de776ae221361263ca8c1f9cf84e11d1c7b348568e98f4eeada5efa2f9cdf7207e334204a923b07c01eba31d6c164593efb7cf2f7bf32a89286e4db615bf1d3853ce7d3e4e81b5df5130b329dd40bdb2cf78d07833d348ebd00767a75cde265c8f4c252d3a6934201809cf3e5c93dc96d8718f955a1773b1b96e8846921a9e39de819a8ceee05cc57a7733ea26c6a74950b235b676b6c8d76e076d99392cad610eaf9e6b5999ae89f8b0d4de32dec1a8e4e2da32c25160140eff8356eb3f8f6987aa96644916469f0bb14452528c5fee727135ef9a502829cb934d0360cf21b819e57f5a4fba7dddf41b682e389b057a2b769c6e08038fd8b134d05186251953dcc9719951f97892a554f66aa5126c8e56e2294037b00a226154c4d5a8c5b25ed11f0fe6616b82953738e3c36d89d24c7f9ca47686bc9fbf99aa0a9c7c2f1a760b06244c62bbd132fbd57e4e4703750a765dfca7c4c2bb62a4771f9a3f2cddf80e3315cca36b22edd9666c4ce84b06a63951166ee0b31a308d8ab9c5ed30bcad80a4c5e0a5b3934a1bdbdc9d31baa38c4ae1f08aaf93a5ae7bdbbef15985ae46ba64dba7e2e8429f768e85c1b5f474e6adf3d7865e67d088175e19dc4891e12fddcf109f4391149eba4182c8b40ce3168e72d8440ccefd028a3564228b5a8bf50ce0d0bdcb715714de7c03223b3fc5dab9028ad5c01f70ab462bc9e47a9e2c52109d74d4ced47a69bcc3fc804571b713d9acb2351b8bcdc8512c11d3a0b880a4958c8ed915fdb43e7c809548742f26f9536866e0965d15b4b4bb4be2129bd4e370f205d422a1f633db0c23aa4fb9c56cf912ce06f4550234354c95df76f41bf3609f86488f1905dceaf4440c4f95ef54c83609dbb40bb9f6f3bd8716785efd634a66d610b9888ede8cd668345ec19bc8be57942dfb1a3ad557317437149d792d33b09ba924ccb6501ac735febd81931b8b99e4dce293a739d4bd843cff676faba84d04e1854dc7ff87e51b4d41cc986caf683f235ab105895c7b9a502edc36d3ac8a38ca34f2a709b98ea08953a0eefd1667778b022b8276299d725f719f787a96381278bda1dffa5fd74787aaae8de3608bae7a460099e96beac67ebd42c4fc9df4079fc6ef0fb090748fc956619d4077cadb58684a268413d174ef08c37627073ae16a6fa2eee24f3f36b358bf77e69cd0eaf23876961fe8c28aa98e1817c7eafdec3271393eac3ece1e516d99413053c028aff6fdf41775e8731748d4558267df4c32b3b0237c7ec7da9601444ac2d9e59e8f0d614700fcd1884d693e67f609061258dffb58908344700daa7c5d9bd996d7e622fc29ca0647b083736f40f6106b83594970283950a0c26b83b0dd5d685a799f5b707c5884121b11af49aef8d49b7ae8515ee816b3c3477e1d646bd0419bed03065953883a06575c3ae5838bd8dc67cf27e43643a598f812caebd24c460040f5f4dc424a80f05c4d419c6e6df29a7fa07df64214aba35b13a4fe72e83b3db5e2800814a4f53cc355dd74afbc6ca93ec7e05b15fb62c5fef70b44f1c5fd9d3022119cbccca5de2e0644ee6dcc7bb6b481a2cd30881efa4613e44c202ce250b4e3db83803c2d69087f7f5139ad9c237c5dcd27e228181e4811b4f5da9aa049e43f900075133ab57c4a89c0a47111d81edf844da54454168ea076aad8258c8a323e49b73d703e57afdbe1a6ce2733faeb53b50200004f4cd66262ebde46847384978dda705c1cf8ef1283f908a4cc82f6c973009f88b8cfd7417b0369705116d8e6f30b98854c8f8918f488c2c932b09850825cd5ebc211bf2869d07d0c6d757c2483ab50eed00e6581e03c8d025b89632d9da3e19b50049af1116244447a79400c9310eedef3dcc131dc8ae54d66d4760de40dd3d91fd36a5fd95f985545e1449ae5431dbdcb167bbebae823e8c5b44fec3ea1860a94234e2cf88b675d1b4062e96eb20aa0d9f6a44d345e21d756cb26a9d18c7b98940aaa210981a6fb5e5442fe2e8ee1b8a8c3ed7056f2e1d501cff81c62a76ad4d9b84786be2339d19dd27d439977c69ef0b4eed5aada2af50467f2d40cf3764b1a098ba93ee0f19ab8979e865ff44c4cc93b882b66ab369202588a4e816b3ad7ff394b041c092460f1059b66ac51dc034c3089016ccc86747bc7cded584cbb1c3b839082ac99047df16e56a386f707538bb11696e5d5c619908bf0c25109f2e9d411bfaf99bd663f0bf7f1fc9e6c8cd5c5004c1e45816b9b096605bfad8c9206e9825197ef140dc67c729d9231bb80e6e3482f714255da15e0b762752c0b6e50259a539a2027c6d568276cc35cf51cbafff10e27f19d51328f69d3c03396eaa28f98b5eb4979f2bd752ccb485d8b5f89720bf13b71abc99250ab07586a307a12a5b04c0ed0e3c53bfcbc85e56b1bf4c7f7b3409c9d6ce42ac6b0fe9cc14df2f72791a67b91360e6f42c7a7a98ef78c9e696458d511a5f83018465f7d2a8a9f20c6d0c0c8aa9d81611f0a9db008014241bb61f03d3e87c3524a730fc5ea764c673a2b1d6c1acbb9a58f1a3c67ef333b90b8b3007e7c873cf4b9c109931b95c51968c8ee60872d068ce9413b4803616f88530433312124195761334923a46cae89a0d0daad9ecc9e55687bcdc90c2d2bcd35493ab07698d30f127e48c5df50a617cd278ee29564dca33783274d1680e408699a2479af1e98cd13f00480db7bd77168d7087efb6b1cc5fe462d386b72948a1b401febfb308ee8708132b04d7f793a24d4a994e8bd09963246d7956f0ccb3d662de65ca5526fb463831e1c763e5559deac90a0d9f33610726985e34448db39feb0bfb93fc5000f9a055a219e04dea6859be8d915abfca7f89ccca6a113e5e003007288be2c264117efb0b66dd4b4b78409e1c98f192137ec41f766c9f36a9e187300aef977e889d0434de2151f5a00019aeeb613b1382e776ea4b1f52721d0e4ef38c932bc77d7c9fb0aa7e1cf4ab777ad526f42707a7ea6543a1dbeaa286dca06bf7f335c869f0e26607187971d43318b39a47175bed924ba6d0d4aa7afc508ca0da2c79c2455df4018420e21857444e3ad6655fdd1ca4c1782f94f5e2c1153f2c593b5dde96b908b5817ebb18e0ca81dacd2e5edbef6ab32f79667010c3a96426b435cb294863e9378a8490b032415b0c646b316890f0bbd5fb275f76192162a342b954e2d660f92fe34b39e677dff87a5c2d9e9f8e0d892a57793b23d74072c0f24ba4c33167670e5b7865b64ad6aa25adaabdb17c931587170bf3134719e6448a5dab23214767af47a8396b4e5f0c9a162adb87d4863770e0d0f9c5e25907a23c8b4e7a68a6b7e25b902d5273aed699796e54fb323e37de635205d11a38253a8aba649cea7059b132b04a46d9c1df77aa6634025f818125dc1fe93f1f3ab225be96cde61393873a6d0176d914234d0a8282d61cdb874d9c4361182ac81acbb5d11ad91c1e165bf292ef4558fd37f42f0470c043ffbbd340bfedaac0c34cf4421cb74df0f4088fc3b329a893190532151e920a8685e6347b2da672f7b494cdc2754ba13f23a4a5686f3e95f9a34ba1420cc9f942a75fd168695d05ce85f36adc59dcc542f75c421501e447671be2cce3f95eb991e06076ece5e402c28932b52772d4f9cca926ea068b5fdcc3be0f3049c9f985cf3615f2b8f54604c705813c50f458681217c8b1d5a9be7d93954cc865af6b0e7a3a8da4ebe45dae33cd8173bbd73ed73869e2099dd29e6e0cd941ed6638acc944dad340111a86a6a08670f16fa20e4d4c212282c1161c34c81522abfafd66f20440e631d4860cec23e05bab69c8eab77e28974a96f56606013c0e1862b6c648f197c267f680761d02eb92bf493e4cab9c548cc6cd8d37eae203fed2c9e74d6cb6dd3b6d10f387be2abbce15c93df817ac1b7ebdd14113a838b5b5eb30ff57f2ef219b51f04c0abaab42c41a9fca7fa36e6b554a76ed9aeb52c1f62857fc9e2bcfd0b763b9505fa70e8632a35103ba086599fab7dd5b77153277b9edee015c5d37d146a853c49dc73600890b73905bf06d865fdeb37add163df3cf73ec8dc0f6243e5b05b09e89f2d041dd4a027798caf48a6bd39e316c1ce4c26bbf69ee7a7f0058b74104f9361596aa4ef5b2effb7b676d5b94968bb2af88f717e8f9a3840d5ad2b97ed90f1b813bfe070fe4de871699830157f5226768df149edfa86e8580df2d2a0dc136cd17c9d1e85cd9747538273539574354097cdb0e48a6ceeb225b5937fad5231e4d4957f84828cb553fda06d799272ad3f4bce89406ce060a7c2c4468cc5cca965c59086afd261db2f56b58021829a0186869dd7d27e303101c57963656673c26ee0a236e502fa41d52abf441a462b61d6897ce569c118a3531009c1e3a3a362f16f3b22afb29e7b52b511841c3fbb20758af81bd582df97f2cb116a343807acdf523319c96d4930b8cad500c257c3e45b60a0020e8f87df85cd1fe1f49ce9a3fade3ad138775286a83c98563c1e14a24037445e5c31104158064163cc478367b2591d1145dbb1019f54a282fcacdd22e9917050730b39db44da2544fce848ca65a52636847c0b45be46fb1ebda4de049388484330625afba603130802d534acff268dfc6a1c94ad780b5527df93ac4fbb03186c4c1428476b64f1ba319f985adfd602398fea4d37e6cba2c036947d306a1d98a7e433a6cf4bbd901d7ca29067980ab83276186120c09cfe03511bb87500361892160416e4f6bc131c35714f17c8bdebe8f2c21e85e5854d29a562e78186e67886e19ef28c5b6ec6adf36a6c3b240c79733613c3bead86f9f87958aee809e71b5c13206fb699275e54a3c06aea7a076bcd6f51797c7384be8452cd9fbf5319120d0e7d19bb814683722bb211a44797e7ed77860502fabb891900845291bf3eb7f0d3ed8ebbbc235b5fa2829e60e3c3b9bb9f062279acc4ec827f16536aff23b58d6d6dacfae40fda42cd1506f7bc744d69457682d1d0389de5b2e92bf70336964b5268989660c90f4c1991aa2dd0e84b0fbea19cea046b7cd4c91d0ea40e8e77f37755fb91285abc3ad987f6754cada54d6707ff580b709fc8cbb909a9e469fb7c301c439c74dc0ddfb89b4cf3710f02faa93e14c031fadf4cd60418e1baf26a83c0bb7fb666392ddfe33dac18387799d06e7356898efa41bcc041b5b24731e731dd67c564554c2c01951558da90d02cfaa75f8a949ca7cec6e880f287ab76bf0123c2d3eba5e26640a12bf72a8a114d61c0f5e16e1d21b86f560427577d497b0827e56bd45f1e86da4a0b1766ba34727dfeeacc8645c9d06cd3f55690c3fb7e49474e39bcee88de2205729d1e4d9b0bf8d8ee20c23b59473e77656a802df391e9eead21a169421dd14e161215c5966d6bc3450a808c5e054ee7099f231710247f32474a71b8c065108b1129efef5a53b160dea188965dbb3ad5a2216b50e0cfef96673366fc327f32a3e2065c2633aa815fb1e5b0d1b3ca9f9fc4b0f8cec1afec7798ae0fa3bb37041ad1f6a50564c562d93f2f7ec04410f7bba082da87409fc37c5dd166b5167e38c7886f7902afe8a7085809e3ffca59167e20f7aa799d4e90b7ddd561727a5d89e1fed86638c903bdb6a5dd17343b97815f810f6a4e7e72bdf6d0313b6c0fad758e1f0ce4c272c8e804c48f56ad11925c06cf79b9738b717a6d0ac0561da78ffc74928df5cfd767dfbe0277b3a062b169c1b609ca2abda359b1cbbb3e4059cfce7ba0f72b3f54c3de4eac3a5ebd73101fd71501ba6d1a3ca3c245be3b5c107c92cfa7549650d404bec822313fc2ca0652f2197c8a9f0e61a5270511bb36d065cc9c25d0ad53fe7090177eb3d77257f59d5b4580b7e27b9e00426cf78aaee62a3192f70016c7b3ef65834cd0aeffe3b806bc05408b5855fb45258986baa040f680dec18fea6027e7cf9ef9bc8e5dc481eb3d3d145c8c02c789e30d53189ff23c724b8511700ab0fd4e165e1c13e9840ccc073996245983b1a4214b0813eaa8b08ca0b964d38fd81d10ba3cf4ee1c42fd4a79104b413efc31bddd7c557fdc9604e710fa79e85be74f1acf3902aa82872ffbd97341c9ff889a692cce2b5b925651e8bbc11dce989653fa9dc05498db6253d6237765d3f5077f9ea11c598f932b01d2e00ad8d37642605be9e390696d7458287ea42ed95c88268849a62c35d9f37876b0084171e6898a9d338863cdc281b92a78e67776d1e57c1cabf81bd965464a21ad1288797a1d11bf043321fc7326ff3df51988a40860f2724b4029e3dc130072b050483b7e83e400340406b4e3af991e88fe710f0b26ee232a4ec8b41489a814f89395e455f653a76ec896dc465e506f3b22be78e384e32a69b590ac7caa6538030e409b3dc3274778bb1c269f9305c7293a87de90cdedd4e328e252606b48de5cafed77a4654afec5626aec00e671226f1b20d07483ab3f12797dc28a055d808900303b99ceab5904d453e4ff0976d5ad51dab6611755176c15c78f7144718e1994bea37c98772823bf4c446249d74bd260c01ba94523bc359476ced62ae38b507c01ec6106ee17c2ab8ad9dc08e6b7b416394744e5326018dca1dce9f39a03cf7550f70667a7597e2c6802f84d5bf1c83086215983aee4360bcb70c1ac6335a5b5189e86b11187da08fd9b64f769723a97646a72a5fc8a0029837d6ad1f37dad13c5d36021d902f605ff072435bd455776433052b4a4de8312a90958700630ebf60b3628f9fc7fb07a1dbd4240d5ad93716754d255862af51d08e74b9877106b06b3667f82426dd924bcb3a1c6f2fbd2db9d19a45eb14919b04b6226ed843631823844456ac712f396d2e719cadeee8161be95e054afa6874335a1a6e6f946c9e2c409057e2ba47478d7fd6d5fac03fa7aca4e53fba352c19025b56b9d28f8471c325a4d328dc66facb403a795917fdc8fd6b97d4a66e79423122806e64b6ac245784faa79ecbe8380ccb0d0d503394d356602061fda7795f0da35c05aa02db82d46dc3975359de91f837443e6e9b4b45050d17073f90ff046316e95e88be8ef9f7baa5328654677dc841c81d5ef202e3c625d5cdd23660300b9ba132610cdd3cb8d6fbe245f75a22ef9a8d571165d8ce48f350c04037f3979c1b6717f18fa5f1411f2c06f237055e6dfaf78e093ebe92bb0100557c7575a1504ec2d511c50379e2247ca96b14ee1566ebaaefb5d27cb47d072a2c5b58592396d1ced4eb1bc906899dda3e661fd1b01a7ed6e0def6c8b798a08fa0c5384c327408166d5c939f7fbac55b545632d222837280dced578bafd9c43b2f58f8e74749067215076c69f3881f34291f3f746884cbd512465609a81fe798ba83df27548c170a79fe7a34f7db33738097cda13b63f145ff874f5aa200f8961aa3c73b59077c64a6237241a11edab6500b4db90a375a2d78d90ec0c9626ae4ecfdcf27a5a9bdd1b3f927ce04134397d4f92380b40f1b133ac780328938cf39a2aa2bc013f3ebb829698dd2454b91f452d924492f307f68a98fa734d670648c65681a569bbe6ecda771ab449f35fc5120caabb1dbf165f98bc89b79e3d400ad05dffb27d295875eb6ede093e4143f54a9efe5a7371f66a727c7d5e80a98d416318df4d20b02725a280a4ac8905685984fe7b44174d72c3c53510ddb91853a2c1e18e3fef92a1c792e50b95ec86eacb822bb2b7350617472eaa901746a7fc7cbd0822b623935660773c50f9b5b2f68a48f547acb67edb01e479f72f6a4884b2f03c167ec2f7bf9ddff626e1fdb84c1fb71275d47ba5541d5410d9f7edcc2254e6d8528feabbc53fd57655d65ab1e97bc171a67c23a70e9dd7fe4ab658c17461951e84a53cdb23064f32ac6357f2c17d76e9da561d39cf7aa64551c11e26f2ca5cfbf2af6ff7079b9fbdb7bf872dcebbdda6ae0dec2d122823d9730a4864a36776951c3882");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.setParameter(new ContextParameterSpec(Strings.toByteArray("Hello, world!")));
        
        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));

        AlgorithmParameters vp = sig.getParameters();

        ContextParameterSpec vspec = vp.getParameterSpec(ContextParameterSpec.class);

        assertTrue(Arrays.areEqual(Strings.toByteArray("Hello, world!"), vspec.getContext()));

        // check reflection based context.

        sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.setParameter(new MyContextParameterSpec(Strings.toByteArray("Hello, world!")));

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSLHDSARandomSigSHA2()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")));

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();
        byte[] expected = Hex.decode("7c65a4abed5a4926316228c52d815b0086c8fe9991254a563db365e340d056dabe5b45ce9e46f8c64fe65644d3874ccc9ce314b2d12d4903188c110fd21a6e548aa995f2c6508be8b60d620a906a0c3e394f31003ee12576d9847c508125058d1f030dd91c5da0026190f3b0f5d18051621c87c0334c644552ed94dfd8868a13ad90d67471f6ab3891a0a8a3a374500faf30f22c56bde568a89736d0a03203a23ca48135c86939f4e9e3ece6e3be79e18d33bed0b3ce7ee69922e08c0a7ecb1375ec93b0393b7dd4a3d64a8c030d3e7bf144666fbb67400fd38fb3b788460eed49439fb2093a01c21cdcef6f2ddfe299a3bd3d675949c3c04390a9f39c1a0f4e99e6c49cc8fa3728c0b9fdffddcf560b791c00e41a09c3baf99b192d519bb6e095045795ecaf4299bd286fdcb27045ab863888807361a7497f24e014618376041a49049fdb572b19d0da9ac4d35a7fb6a9d18cffe0f6edde17be904747fced7b670d7b0aa8f4706facd6e1fda80b08f62fe2033889bbe15e40995f71dac567b962927c16a08c1c2141e5d5eab881306754c7367849195538a8c05eef8bd1036962aa6a227cdc3772d3f9c142f7f74661c2daf6a094948765247a0c760851b731077496222121b5e7c852ab0021d37a4743242d96874d6a58ccfe07490415b482de7ab164dfb19056c93bca1c0260733f93ca7294e25c7bb117aa37101d705806ac8558d3ea9abf90a500081b77b657c515e2eca4b3058a3e9b63fa8b7a83d0be55828fa4f12e7cf663624224026ae8935f1b99b92128c5ef154080f66cd361c22d020dea778aa400011d212900a730e45039dbaf9f92ab4cb02aea28f1ea0ea456c399017b1a7ed410874aebdaa94cd8f54f16abd4b0193614c5b2f4d28bd3fac84e4881c1c92db162d9a441bbcf668b8acb050721ef22e79c7f9fe8675dc3501c7dfeb8f691d5ce390905d3bb0b523c1ba4694e0982669ec0a96aaf2b0f72df752dc627d71cecfc027e59d3ed440776831e2a8ea09436a504bd30c2b5bed18e4d5fe270bc5ec98e2ccec4f2f33b864f7912f45502b6aae2a9275e4049c7e872887a307cae2a0076b1c74cfbdc1ea8ba6947e683caaed96e84f451ef643e4d766e18ba6dd05e7ac46432957bc141deb48940261200444ad2e6b8b7fd5895c7a4e80b494bd1b648b145de29b718c7768f16dbfbb9dae1c6f991a57664aee425b12796d3739c18d532c9b3c37e8b634b16fff898aad91fa3b20853183dc6ecd535db1d953f421c2a195e781763f7c8117c6204b8f27d5ca74873c5755fdb96101b8a43e430207ff7d1a661bfac71f4261080df592a700f6c687b788230cabbd240f000fbeead9d5124dfaab331b709ab4165efc89a108fc5962a40989b8b413140196470e723ba6c45fa94dea7d4ed45c7fdbcbab9c3878493ee44ad35bbdbb77553ed2fd9e7a20dfa55f1875d232333935bd529eb1dd1d3a2f5f0b291c31d3231a719ec794059a89ecb2f12fd6bf8b227bcaabf0d43a9791f8f9190c31da568df59774be74178e08a80cd77ee6ed3024e3f530a4a32f2f36e2369b6a7e9d7411b2233e7a1e80e43b208324daa82bfea001311e00ebf9ce6631ab067e42a411597db903552261c289a619a459185a44a3cd26fd72d942df7a14434c0afc1a4bde8064315973d26c359c774bc3e4ca183c6f9b5c60c5a0566156ae9cea689e4ff1364b491d5b49a18712a468a2298994e006378bc9fc0eec56697b24dd0c4e2ca2d4bc52f3fa995df91b158ea726526700100067ec6a419571dc6a64bd5d526aad6f375891a04d8d81e2204bb3fdf7ce553aa90e07e02d3014bdc16b9a3d08f5d63880a36e13c30790ae3c7cfeb67061bce2138d1b9124a95b1f5c3c0f20aceeb7c311a03a0ae11574890dc998b54ec0145411c773340b96a5a6da30fd9ee7b56142414478e0a78f9defb187f8155e6632e13e272f8314621214e5d552dc4de3c8242d618919f000f0646a86ab494d9e0b840f13a457449e95e7803de4897b2545fccba471c44b8bbb760e84d173518672aadccccbe7e8cba8681e78067fe63bd83f26afc04fe93a00923fd73707682c377458bde04d4a8b4a0f350f6eac59c10c8ef739e4568c9044bd3d22182e881bbd8f727a45e1d7e666befe8c3640d325284c29bc22f3103ba468e9dbced0c9025a18248bd822d4652a756b6643b18590c6af2a3d77f72061d2ecefeeffb7fd0f770cd022922c72454d3bd4ceee3782901a5efcadd2b899a92a5099caf8ed66bf182d6457e3279811cb712cb269ae6a484626f27d86638c586da27fb6d5cd1fc2ecffe7603fefb346e76db89b9b714f3e0cfc3b5d7da68ab332371d3bad9dcdcdd294519374779b0fc0216f2a2c938403eea1a501906991c55233eeb63374273076a72f77144a06bb67cfa70babc7fe5f6739a9e808c7643bcad6f20da03f6071d7296d601a4142d2bb9f015c7adfde3765e011097e5ad4b29dbe47a50f24732370a1b471ed304e7d0eef3a2598e470e60d8d61af0f68b10a10543182abec726f27a452fdb4f669b02c908349e0da297a5af613f5e5d48ccd83ca4be57e6ff79ddf74b31ad8ae715abc8b1284e1caedce4928925301b538aedc0e38fcce10fc91968ba8a68302755b9f591bc179e3e31e5f820110328dcd58d46cfb71a1fc29b51f00dbc078fccfe00e6eeed39bb49a846e2f3674cf79b9b208d726ed0615a5498d8883bde48de23336a13935a38fb95a762ecf4ab53883dc434b4515e997a408494ea2f2abcda0fe24b4e9395de6cab707d924de8a3323de5057c8047f97ca27f9294aa319f760ba5f78a3c834e96bf89a3284cc584139503665a2813944fb3705aee1bb866cf5defa5b26c9d9169286fc56adf455f6c6838a2cf20358dcc081ae06079eed74b3fca1ff617e24fc2b8fbad7aad505ad1de9105bd59da2afe2cefceb4e7d7ba5cdcb3a43a40b06376ec8f7921e9b4abe571d2a62015107d107bc7f41b01a0eae20e9495b4b490cf9dd451201828e8ec4f9bd3840570b637adb24d979d361be7940fe570bfae66f0dcbabf1ae78fa516d106e2f980a74a39f10b1f00b1e96046eca047b471a212b26027b5b13853a2eded38d148e0d8c98be3aca48f0f581e9ae091830500217bd4809c5ca3d38f5939fafccd29aa875afc61fdcf96a1b8e207268693d8748068b9bfd73778f5338f772cf0287322cfff67f7a2f02f16fe0c5c0edfb0a4a10dbed23f62a6324c84cf06c3277c8dcbaae6dff3130d3af025a41e0fb06d954da1ed8ee8b551001b2ce6d5dd3593acb8fd641ad822ae8ee5fdb97fab411659dc6c99c8dab505637b497269c2f8be104db9f1e8ba3002866a2bbd8f6395e6652af64ec0153060f52602b280f64563483d41c8bfbd8057ebaae1c7d43deb5355ef4f4076c9d8460784eca581dc987758440624954704190d63e77ca6ae535b9c81a1dd84f3d8d45c574617d5af921ce78c10848477730d36c849603ac80100bbc27a245c38bf9d3c04df16b0e9fb4d7afb043273ca33e5d0ba9ab71036cfffc4fc94fe8957857aebeb1c7d13462b205463a598e88c28d2155eb7cd136e86b2fbb2d453d7466887601f912402861de0239740b61980bba4cfbd12acfd7c77c74bbab585d02230492f01090ce439bb4a62d87a11d55a99fb303ee314ebfe7ce91e7a0a7a09200f3e27b07c42ac239f97bbe30b67963f3eeb86293a134b7a78978e1599529a17049b377245db909e3b4daf464862a15e38ebdbf484513717d485abf438579dc03fb7317e1d75e12e290afbb946aeaadffb449fd6b06edc3024045d9aa98932b065ad4ac89a2ca247a08c7b1c6e6f5498b083af3125e68c30c1ffb471facf43138c290be05fb29342c350bf8c8d428004cce0fc132b1e39fba0cb7e2aaadf0adfc97652ad18ea7c8dcad8aed77c7db021a4fdcb95e24b41d4ebabfa264c1d3be58ad0d5256e423b39c61b6aab8be4868d4de14cd7cd57e4e19dad9b5563298a2b718c7b6e312ccfcc37b21dd491b9f61912f05fc991df9ba558b36234e50c760ebef42f976dd42420811759b5b4acb4ad02fcfcc52a9ebf8acc042653b68c34654fde992916ea63ab346839ca1a921404269c3403c6d45f6802616cefe9beaabc5c2b4b1409de4d64f262fbad635c5690e1d536d12f0eb8776cdeace37fa2af3d2ae9ca4628386c8fc457d239ae2b12bc7517d48bb4230141554a6eb709ebf628bc79297bdec16d72e3827ea1e0041b94795ea2915294f904d69a6538475a59274c62840394665cb9dbe1f004384d6864efb17caf2602f9a3dc1eaf3191286d0dc320e796cdc75197f99667d70036f23cdde384b10bc42b80f420b92a5b68c3df9eab25d2c1e42b57c2e831f80a177fdc10037f38c700cdd0b0f9300cc9e216e77046771b8f6f40030fa6d3ed244f7ded3c05904b5f9b194d2b51475988747ee2cfe277a9736ad7362e304653b21beddac32e30d9c99ef11a809af2ae602cd1c4ff44538b3e4a5dfffe03584824d6475da866a49b0e1b9b908f78928517125f64e2e5481071c5bcbb9eb55435f8523208021d67e80cc28a33393356bb11a14f0513cfb0a835cdccde3a10af0e38da32ec25ac50b4d728b994d7e1a9147ce32a470645380c6f447c04e1a1535cb0018fd25f4e886514e617564937012da42d868f6c0f4697a26457ecd7cbdeabf298964c67ab1594e42af19a28cc4405ac968da3cabd5a34a86199ab85dab34953882b5c20d7177b4807d036d303d6140e975908fe86b9b48a4c689627f6003a6a0aa753c41f5e55c9c99516c10ca47a6ca4d8de9d5e52688f6c1715f16e731c5843a2a7979ef5c3d5b94b2530aa8eab356c62d15f189c38bfa2ae4e6488d476d85cd00166a6d100f14f44d612dd4631bf1e2732dc3b547b2e8b2946f52124695287527730744e91a491f17be7ed0ed7c060e2f053ddd837167e4d70f67455528d48ca7eb225f75184ab4e5348d3268508c1ee7da39098beb8632c50e5c71f71e2e5e651caf07ddb237d8b74801369088732a263252493ac7ac9ad4f25123e7464f5057a3fc99b19905666c43083d3f5c9265277707f27fa604a2d5e84848cfd88773b7e6a3f78981b5e34b5bb5a8bb20eca04db5a2a5c01853083ef716ce5b5981c66f5b6254d545e709b347e98a913314d2aa1e427875ad90d8930afc14ec92dd95953d7883438f66ddb38bcef5bfebfedf8182323b9ba999a6454e568963526e3f390c26e570eb90510180acac7fad3884b4b8f2b50358bc576bf9f5789db0f4bb39c486dc500ca59b425512013c1d98c06adb29c3b15e0ac9cdfe701caba233e7b7f7f4fd2035c9d642aa5932b12b57cdfa1595363e5e3f785ae7cd2fea7dd5e29decef35a048dd97a8f1736341fd0706735c746a16a1fd92ef03ee2dd5278261572d254518e65569a1fe83752c71a2cef7875b21e115da82888cf37cdc893113877ee84d69661a2b7fc34973a8dc1245d10940f62f21e80b463f6fc75795f0353dfe94d70916ae6e9bab0fcf01680d13c9f2e57d427a31f7342c591b96ef13ffdc036fc3e6d75864e2c50a676638e9e9f69c4c7a16535f4a1b36fab3b58759d83c3a668c718f88a3296d320235f9ae65e7c5811dce32d5912f2111292cbde2b2c70e6619ad5177bb4829ad7c3a4a00412a1cb3033eb930abacc7ca1bbe9ee5b50a38dde54b2533010cfa39804807449904f76d650739dbaa0b08cb72b0c3c9b29d7ceb8d0a8cea47b126617c47ce9364a6a0a083fcf5ac152c0248cf78c576886d697433e4bf6b0fa77864982435b9628f78eb2678c80899f8d413aa72dd3f59a1d373b59d85024e339bd54adc84ecccface73813e7205c3a4079402a3608f24c8fcc788c071b9dadb1068b44c19219c20a3b33ddf5ad87b223be873379d765733d5c8a05f20804b7db1b4a10154e2361f8b24debc0dcb51f6e475f52224dd5ad497364084882043a04302fa4c24fa5c0a02fcf82ae455bafcd29747ba78f1660b40446dc188cf4655c852bf3b844ec40f0c9b2cfd81299ee699564a651d8ef00198ae7d36c833fea52b1054b5a693e76d1cd6190d71dc442c071b2617b9cfe5212ccf925cab46cccac6e3cad2de50f3fc787aabffc489532a46176b39c214b245e00c9333eaad119538a171916e01a94a4d7ba42251d4f3a51d5f2919a845458fe36573238c8c5aba5d6d5c18fc3bd0776ff88561325a916d2ec985628cc9ff1381e219a0c804f94fc8906ce073fe820c2520e39e4208c88721cacc1124d9787a54456b93eee9660c16d2adc283b4cde456c66060fc4f6c683a0e92b7d048400d539ceb55ad6e38296ff0aa7cf7e1f5bf88eeeec51cd82b1735299ffc59c3a807d809d9ba1ec57d5104d95c96e1d38df42997083e70f65bde2861f830559c9c4de92ca0f1acdea5bb1394024de73453ef70c54dc26e8dfbe42be49d4af77ff08c220b75a15fef3e5ccfc6af5da4c353aaa85326b49329eb7da7fcbc58a6db318b63a44501ae04978a45266d56fa36abf81dee1beaa8c244e80872841ac772a7b8b1695b0f42a090232a61886c9cb36dfc31485cbd4486d60d15914b67103945448e93fc24b2f640ade543f393c4f7a7fac43ba6d2238eb8bd5a010b623ef9e6f1559550d2e37957fbde3ef4952ec65e403a37ae1e91da9399d6751fbddfa0e98c44f6b279e47370fdaef3b99ac02d46beed2308efdd6e0f21d8020dfefb1c46bc2f164b707ecb74d5d8763e31f4631f0231752cff0fd90c4a9565b5c512497a5cecd799a234a9989b7f1e7e26d3c57b8bb595daee9319b97b98ae080a15ed88a7d9bb47a5c6d493cdfc51b6fe54cc8577a15782776cb2c895dac267746426ff0275703cea45202c76e4d0bcf5b378a459e25c078e055bb225fc0c17555b3e28d313a25d1ca1a24cea6e5c527e3b0312a99a56d5fa80610ca6cb2e294c41eb8aee4c18a572b8e600694691b67313d5594e0e4ed7e74dd6a95e2f5c66376d2e3ea5a484f7935966d7ebbfcc99a66ba7232691d212b2a1a52f9ba586a03832e13e1da4251dd2f78e5940aa3618c6814bf544d22e28782ca9f71622acc7b8ceb73bdf7b2e3a61a3ca0a8b3c07bcd371ec3c5537650f69fd8db5f862bbb7fa2789bcdc3181dafce8dfce88ab29b1c102fe1c9892c5a57170b4c472e3627c0e7660215f63e27c1a713a4a17485b103a14d4a1ad3d5ac3051479cf699f54bc6a5e47c9654260c5d210bb083c7a7a35b7ec9b4944037cf9befc70e440a7aff4f7d68048c7b8086574f7e3a9b7ac40e4bb7787d11c435ea5e698a4409486f7fa76e2852e6f5d32ceab5d3bc75532a92adeabf09fe54453c8313956ac94e016f140df72171a07e3870ca69a33945a3beec5773578d43a3c7f3ca92b403c8a2868436440638936f859eb855a25791b789f3af3586c7313082e4f2f73a4f31888e31ed32fa2bdb7c3613442918477902f3a9742d98abe453a354a45628597139251e86e44332d2f0059805dc33ccde0621e54a1dd53293924bec6401c1296c11fd03146ada01b7c8c9357d3aeed6e2607a588fe4ade46f1e4d37c9533f7a00cc4e29184322369ea2501338859441e1e93ee09cb7b42c42e2940697402d983fc1e7fa82f9054956b09b52660bb8596b3b017252de3c9846a5cc88eed042eb59308798ca7ea6876026b4efb5494bd3ec94cce5e5ec359d4ef0c6104e256dc4a840d030c6f5828de7397d16194fe5d6124e0c08064ef3f3e7dc1f035ef9a41e35912ba68eae57c7a47e44866ba91593c6280c3da79e8613586c121e803af786f938212e76dcde4156e763934b6710205cf2e89273a371248d2c444905777aa2163196e709daf5a5ac7670bbbda5ef6b70e71dcb3f36a8474f318cf41ea4a328401f305ed3e506974c9e9a66c3822fd355420a8d7b375ba42505b5ca09d6f53f6e0b6cd677f3700bfe5cd99dc606b1d5034000dbbec8f98dd23b36ea44fae92e0b3339dce3bcdd0f4f159ddbdce13caddfefdd3683ffcfdbe05fd8e6c7f87e5f726230fc6aa3c66b752628d5580ba828c79b6ab22fdbface25f913465b76cdb58668e60db1a1d7066f60789c08d6f7bbf5b50224ad8bf0f0c097f088520b265ad6973a8a43d740f4121bc335e89c3e4b8734840d7a76b961453a2142069ce0f025be0317cd7ee341e7162792168a9efa720a3d23a7ea7e06e3d6d72710f30f617324cebefc8d0266e2d7c6c72d6bbd741abf438092c4b2f6e03444c86dcdf257c15ee2c7149f3549fd1192d5d91891af390f828f2e13a089f48e124a2ad072265f51eb46d06786afdbffa70872c907b2d3781aedb35c7264b60ac7d36f89e26c9d824511f4d35857ae084688a596e8559c7fa58d6ec13d7907fdc1f9338a3530a3ee823404da4bcfd43af2f94583b3e862555e9045bd76f5e6449635379f2d7ee80c7603866a9d28a0f0066e58451eb931984513771065d675213d44e1459d8356351fbdd3bca856e7bf15fe56507df091d40dc204e1e7cbe5fe78a02183cee906a156eee17b14763173b8df6053389e825b72fa1138e246bcd753ecaa58c31221227e8d91abc65fdf436886da67078b41ee364e1800642c437d4e7aa3388847d36ab59aa6010547f5e1d8a42858a777b97c6ea621980862114f1691248f122a63315c13c0312d72227394a3cf380ed5673bb749e0f188e1d53a74c3e0e3f63740683d6922f5354fc42f53cc97d7d0459767737ab89b6857bb456edf86fd874c9485051dda317c7d69d59f134271496bf4a6f59d402c03701f94c593dd9b61c18ce8493a8606fe7e53d3fd22da8524a8fa7fe91aad2d1eaf8d38f7f9e71c122b5f19fc483f73b041d95671c2c1269b2a6f319c1f2b76cdaea1341f69cace60c78e01b0544879381e672fc868084063d5b521d69729986b282dd8da32a221c816b270e520291de331230dda01af303af4e65f2cb949431040dbdf81afc6d1a2acdf39b722c2506d85bef9d7f06f383feb81e5bffb2c12a50f2ab8c1d38c5045734e2f66f4bc2a3b4f5d745f1b80094a5487e2452428746e0f286d4c1610f1cd3c238365eaa69e32e8cbd67b11882b014e86cd9578ba129ed9a42c3878e2f223277d36875c8dbaac008498c2ed97bbb9a05406ca9d94fafef817ff487254941fae9d0e797d77b6f7cc14f1f91f37b4a395d8cfcc0e85773a563da922b905fd70cd994f887543bc6c35a0e8210e239137959ab8380a8f6ae259bd039032cea1efa68bf9c82efd42747a3c5eddd7bccbc0c96d69dbf12671d4ed7455939d4dabee64f11655c548650198caba28f0a618e240ba9e20adcbcdb97251485c0843e11860d3f9a117de40e7d30e764d8b5839a0da0e1024991702c700cdfef8d5af8563f457d0bf48a44a7f0e9d51ea13b8903bac1a3f3933690d2ceb99fd26a183ec5d6101c34c6894fc1b6bd1da0ffab09b0a8bbbf9c54cd2760d88650695386c33aa62b6913df7f814023a3b2e56aa4304ae05b7935f1203366df7acab75f2078c2bb5e6b01312e3ac5cfebb1054c272487134411408098f26c26fb5f181410c5115b997b82dfda05b0e6a9fa5ee6469791b0548984aea213b312cd9cf5cc64a6a3880574c64db1e93ec482252b618d2d3355d37b581d21fc99f3973e9a76fc7fea9c96d1f02ef751a756d23bb2c63778bf5d042b38f2b89522db9f7abb31948950256ab520e0d3b511d6907115aec631d3a797fbc125549109c055f89818ed4f3723db8c8ca0d8d6bf31ce9f3acbf11ca5905cf5cb1f237c661925297722048ff1b51e772c35f90edb3c05b51ca0f6446c7bf1a672bff344a9d538ad4896212448352a0cc1a0d365ef59f058f29a6bced30584c701508a93939dd01acc79e6119944084a4c1ac5581ae663a1b1748d3e34e8ed9f01a80a8a5d10eba4b8f789c1288e86bc660e56a16343881d9466ee869f50c93b9a11110083335b4e201fda9c537a9553048ed88e819494f9e8556eb8dff01a8b9dd6a8a4928861c69697bd1bf921249936ba7c629f202ead82365564dfd38541d3849e8ccfcbda35da37377e80a4196536049001d689ab09c8c183fdc3e8dd70eb25af0570a1a6311f1774db8c029130e78f7384872acc3733156bae2e8692543c45640d9a18905ac8b28eca38278da9564451c2f0173b4ac8071b69be625b794f9d8a4ef0ccfafedc17dd287107ebcca821761ec1d35934160522366a200ed633767128eeac83ba01e502aea183ab8e6f8f5173d5fe6d0faabf51942cc6fda2c5c3377b0c68dbc65151ffce6a09e52b4c1913fc63ea81154fbc6fe2eb99103c1bb5b7cd2b32e63b3788e71f273934c47cb7bd4f0b36550c2a5324e69b08a52a0268b4f6a254b6a33b2dca205b352fb38beeb32e5d7a27bc567b9d36188c6c0d56befe46828b01e6742067a933db93c952a960cc6bc4d8ed112be22619636a175aeae5162c0f662b6f513cd67931b44374022b8cd03c08276eab2cb171da315d77db1f38fbec7219660a4984adebd730c913a982aac5cbd9788c17ad5b6b8161d37e13a50fa1fb84076b5a6e2f4aef766f007113ce40a6652e2ee88d88b0039fe35405c5a343c4ab650128a0efe45e4216550de2187766c1b20138e31e38116e9fcb3c009c7d160ea3b78676083cc17835c049260c9c08b0d1ddc944c1b691ce7de01127011abb3478449627cb02e88f99541471218a2eaa179471d6c663618f1981b36f10a1b851aa29032f7891bf3bc1f4e3204e27a57366acf10aac8a3f48c6d12362337eb3c3b22c8a8db14ef8662ce5baca19a6a25ec56e71c8d4cd5222d3a5d4f1f6b1d48dcc769017e8d0eda431dda79cc9b120dbe3600ce95324dc3a6f02c39a31695e8aa8b91ba70e68bf1fe19f67a21cc92d241c8733da2cda68cd82d8736f7fb00177a4c8523875bd40600ad84e70559257c07bac8a7cfe62cf42f4053213d8166e49323a171e84580807dcfca4d94deee2b260b3c6a8db39de104aaf015ec3ba6fbefe6e6ff8484247d878fabda29d4ee15135d388654f7f467dcb45d4f3c4fdb33150a1b8c2a6b11e83ab03433c8bba39dd18116b58385766c5b0b9789cc0900b100bfd9a8b55c4bd22fb1edb800fc42cf0ac8e66eb4d00dbd655b582b01fc9e04dd687ea3d7ef77f8a0fa51a5a52861f10208bdc4501a075223a26d73a38592f581e918256fbba191fa7b323ec7777ee922a6b3890f5abbe262fd4d6b1ced136b1b90a8a831c10c9c0859b96f485c3b8584e0debd8a6f1bd465f95f3ce0570adb9e83059a8159628d314deb874cdb1288e97f68dff695577b60c0e31a48eb8edf6f2b36e97ae8cbf5798fff891f43bcd977b760bad6117a02ccdb4265ee9e7d433af1212ec5b1fec0798bc2a85702c03a80f398f72e42e3fe1ad008e891db37e9e40f10e0c68204c1541c1f9232d25b4a2dec8836cdb9b4df436de8d4de02b05391caf9eda959299a14f3d3c5f964d7b4ebe3b25b896a417f15fc4db4abc01e7bf32f511294319c907ff4ac46f6ec4079f0da894d7ac3fa9f02caea3f9fd96689de52f8d68694b42e7e0a87422b4ad6c148b059c7fa738e484d4f0f58154205a9903c7da97dee414a36426ef22033f72e1d7c6330cfe1372e79473a837dc4c54b2302f3a9179d5a356985ef6eab02a57b384d56389a95d175364e287eaa159cb1aaaf89e6f1c3a41a50fd245d58f5ab900f6e484d82bdab14d748d8bcf07c82925d369cf71491eb4ed699f4c6debc698fc67595e81cb7f480bf770be93df0a108598d272be9f0922a600c965cff0c044e3d6cf60cd782d47b0427d3dedb7d317f2fc988bfe9fcfa3d9232f415b014ab78d22cadfa7f9178573e5ec3f06885a68474afc40d044e46263cc066140f3a58cc9e5674d297ca1b9afc669ce1d00f081c5f7b830cd177f7fcae315cfba601f971ee9b78ab7729fa2f06e3a4cb87ebd70d172158b4b8c11096818697d3ab2110c04f6ca906789146ed495e3c119516b5f34c423ba4c1c271f288b08646e01912a7c873e8784767496dacefe1a91e28b83c2408ce8f303e4fc222991626f9f7de7484013aeea36df9cd8fd16cdd47b45fe7111de94d7d9638d1bc81ec321e833439eead1d358a61e86d070ae93cbb0e12a365985d4065b9175c2654ea66dc5a856cba6f7a36cbb7223868d1d15679c923f306114e2bd4685df2f41399ff87f252b6427594071a31204887e4764310c412f5e74a7337bece000eb22672a708e98bb7f1e5b8b5986b6252ac06b8dc3f5b0823d03241699bb49bb7182020b11888a660c2bfd3d8790879ca0a228da8d1f97586d743e98fc97199f65a0f85fa75411ededc9083272ec5b09040b525e0b1ecb6bceb038025c13e8406cc9587c80734bf7f654c23ef987a0bb5d9e1e43a3cfd97404117264900949a1034716ec90a3f983ba49fcd8f36003f36768c15e3523da2a9da1ca6eddf54da5397e3e7f02e19c1b973b9722e849625cbfef8eaac005b1928cc4ec2eef20cf7e97aae0107e7ffd94ec9014118e6f5760e1a92c5caf0c563e8dc4cc6647049dda50376e74a925a45e01311f72edabaca059c56f8c20841a45d1e84e849cfc21b393ef83ad760b53fb913cd6cb69a9d255b93ce699e2e7fba28e9759135cfaa7b56fbb721b9576d5829207309888c5363774689dba6df6df6b32a9ee4c582a86d3004c38ee18df2a92cd2bd2e17c097f4a152d4cca7ea5f388c53897d60e77a81095cf977ac1f1f959957e6c362dc108f456846790c5a109989387ed02075cd0941662bdba235ff8e0f0f1d517919622c70724af49dd78d4e59b1679d1f720ded6263e9fd6577cda41647a6de783373f825b8147296c12aeaa34355f9d380780ad1787ec9578bf2f4f5f432a9389eb9dc172766f2bd048c6026860b9135e5547ec0e5f294ac2ee4b03a68222fdbb8d39d6dfa3db7468c47caace1ddfe6f8dcf711a6def98439b82ea2aad697f3510d195da07f219abe10a5c2d9b49e057c5fc18b6cf7302ab4749d07bf5e7b4e355f41a1dbafd118ba7f7d37226f573e24f165f91de73c97db184ec186353e87d9c37957510245e522a92fef11512f620cf184a157a5beea1c4198c7aedd5db14ec49aaf7be8326e56f589beea005f3c63fe8652b8a14761c858a6e75e09eb5f3f063066039e65840c64b9d1898813639eb26185246d098d3c140d504ed99f076914bb03f3be33576fb5dcbe17e560ce4184e7e874f525f21055e933e10ba68a550f3fc233b93d5c842f9e14d2dfa51067f125eb16e99f62f0075f8f6d95c6b7601b58d3f0600714fa0d3dc0f480f5b265f3fda18dbf48110b3fc35fe0652ec3e70e9efaf16c807d793c40f977f4c52b705f450de5a26a3feea4e42714c16a7d399cc54585c4029eb7e33533c6bf4f65c08a8a33095a246024920c9505fcd4fff7235f281aef4ac50e4eb663d1d7751bd2910f09fa17d3e5d0f22829f9ed22ac715a26b508abd2a574d78405b5fbe582e5fa1198beb437e98c4dd96e46da8d99bdc8ad2b0fe3bd915eee567354a024cb632f1286d4b9d873d42d3439f52f8c9c1bc12a101e73e8f29b2c48e36cb19d23e2e9ec8fa60c98ecec823f69b95f1436e94513ae33f4c0e8a0a2999bc8283393379dc35522dda1dfa791285b79951b4c9299dfa99768fe7fd7cbad763cde44b384479dae32ede52da46e12ce5faeab2328d6402ac6354fc548e0fe655ca7ffdbfa2ce94586efd6eb1d5146090a3f79610da3558832e55766333a5f15f2eb8c33e4a352f2ce135c651d829799cec84fc44c28289b81549fdc311017ad5b37ac8388d81e9a3adb40c6910b629736e209cf7a7a87ba344353e9aebcd75577d86bf1b33f41d0e603bc9a26c803b5eea11fda2f6a4c5071001a3a865b85004b4a0d1383dfb979adfff52119df541d3c58738e7019afc60e251eb9767d4b886c9f4db147b2ee3ce9838045411a03e16240a986272618dc8ea67e5f6e1d460b7a532377552ec398a498e2385302533310f09ac49475bb77f30605ae07e1cdec9f9dc35a75ca1a4aec073ae1027dafc259a08a948e99442a335aa9ac54150bbf05caa3bccf95ee47cc8585e7932c8f0e9bc2c6880da04be7277a4f76a4b1b0b22764137527c48635eb141028d3d7991f6ac753bd1721f82d72bcc5bae307bd1eca27d85ba3ff9d38b7756d7e95b66f6b4ac445a387968bd45005f63c5056a018ba28530adf79c0f57a07983bc865b981f2a640e2520f5fdbafd8e147687e7b52ab1a2fe3ee86703ffd2c4359ef4274aae8defc08f13ac984b50f8eac0112bbdbf6481143fe4222140e7488e19b937617b68514f94c6af8e23a0ca161007baf6f2b7f905cdc89b4bc9e858112eade69a825919bb94f3d62cd00f599c5ffcc6af3023355272d2f89a1f849d76446397a672cc8ae7614b8b6ce246d09858308c92e970aeedbb1bf76d454cbee11bb916497fd1af193d21e7777274d2d61eceeea8b543c2394e5c8685af994d527a7f156421aa6b9f5dde5de1cd1d2be2acb5cd60fd04c580ee3efa13a7730d4d1aa939dbc3f3c8e91ca3a98155fcba960a92bd32281c2a20699245c64a9a7ff07d02ecca5bc13dde0de50fb440f3f9ef066ba458da231d680f5dec5ffe2322ebc9d8b624f93a4bc55000e318ea058ff97901bf4a1a3970ca9278f4404fb1b4148c4742b78a869bf045fab04552b88740969d6c2eebf0b4408216ff2f6ed2276e10c3f0c86ac321f80ff491b41b64710bf6959e57a45f3434e771e72011fa73e82246204e28e2fa090cfca50bd3125860fdb08246b542a4e22423633608fb56732ebdb5cbe7e0685b0e46dc0f2e22d90716426157e5258d4896f5b6241cdf73dedf472584fcede9887e81ecd5b47534720e4de2829996276033bbd6be864f93796e5a1a7893765f3140b30b65c7c1001abfe2832989ea7c3a454e8f8f05779dddda4966927c6191231421328949e127ac48fcd1d65b4d00dbf61007ba9e8508ed4e42b05f85b2ade88b1b8708a0eac356f58eb660a57c33528c1eb1202e3ef77d0cc1ae5e5fa751c8eb6acdac63fced5aaba252b15dee8a78645378202b690df8cfb5f8f3d5909503056b5c9177dfdf454c5890295abef08786cbb2842cc6ec0ee948f3206a652ad03e736b7f36996fb9bb6e904a66827626dd159a56a310c52f631b251ce8732db7fa9ef210b5119b3d0be995278199d88f60a3e7bfdc5448a5dcea4874a3e7cca4e30e12f88c1f33019b48b275c529a79c6c3c5060752e37e3469d1c62422d27a19deceb0f09bef08c58f816effef34bc8b2259ef16c8c4320e8770184c67878857b507d3b68e28774658fb7fc29116bd1e563b8e998e62d1103b4cec2e5d05f5fa383d888898641032d6ca3c51f72edc757b0e3905c36f200f4328c584d42d9c278b08e6513d73bd1413d24a0da913f0683459f67c880e7009ecc58b83712acff34fc655d8b447f7cc552644558b9771f205c6f14281d4ebbf088646fb0a8b8880d28ff9f80b41a8df261d55df4c317e93479a2b08ee8a06af152203fc99201839915d7032a03b29403043e65e0b5cf08937d99d8003b78d6367fd16f06f24b7ac6ee3f48ac489b76643978271a86dabb77c6c67fb555979197abca7cbc766792073457f20ebd1feeffd7f8a3ef217d3098ce9a2c4ca6f91b9a4685e22b5419e6caf033888e64cf6d2adcb02a9f7b1a4c9bd3742b46ecbdd32cb7a37061e11e2ec740834d00dea21fc59b2500bae4e51b00de7821902a917aa2acd37f59ea4e4a58a7996c27ffdf1955b9c71bbd83f8d5743de05f75c237a13851f9becb0dff1fb226ac4f3355a89faf79e73272948850a825ac090d61c576b727901f3c24338ba013ef3f562f3aa4fb6d4bf4bc164aef6a37caccb3b07d63524741703e82834860bd129ace09ef6809f2378a87ebda310bd2c2d56097bed5e75c60e06dd6487de90cd6fdabdfaa04c0e06c6bd45048c31fae645799e43377aaa0ebdeb77910ddc919f2ee3e3f13558b110a22b84a7fc77fec2affe81db4483b242ed515f804789eabb7cf1afde5a22dd63b79b339132595cde7c4402c6964ca777a4ddd3118cb1ad0567c1a08f5f4f2f67023fd2c3f2099ca50b60d5827d4d84821373271783b5619de60ca8bc4d8e69a8be5d3d0099d19fdbc20902a7576a501f2ec9766a3ce72d1af6ff0db3a18c282b5b4f268358a06008ddcebc0887350c6a43dbbc07f3d7d23fbe2b1604165f60c885f77c2339b3cd8eda11e2443ba5dc790a9d0f204c5924077100698a582e2d4470b474a3b771479bbca3a8317d655aa742c2e51e8572184e3140c4a98b64fd9ae1f00ad3b33490fe0092833e8aab9a2a6cef22f4570836f39037f616bb31c17d51707b13eaaaad39e63199aeebaf77b39614391c76268e899027e10b9bce003b5795ee89dd6f102056981004a0264577864715442dc712a6c9855c2e4f25ee59d3dae5e903436baa0cf170c963d9c8ba359e26385de615ac6c88f189f24b86269b5fbd8ce8d7dde66c6ee3de69cc9adf55d79b544e0e1d7154acda681ab5fcbde7c1b2c5247cd06c174544ddcac61bbfa43ddf469c523e900e4bb76fd5c5358b78ba8d786c32ace47c353f66dd5dc0459ba912ff1c659d15fd35dcc738c0a487d0ebc96bd890bf7023670ad56e0ce082e4f192273cccdee4097b8ca9a405b23c4fa6c7614b594778c8374b998494e37cfa8626e7a2fe26cde4e6ca9a375117176b795406ba01de08cf9cbdb96f4f825b843d30a9b3ee49372b42ac6c6f00c0a7ef760a8ad6437e789c1eaaf924e5e0135e7ddaf477ec7e2826aa7d58d0589b15aacfd17db6a9d1caac27a684f06c9dc7c31baffa8b2f98096814bc381d2dce1cc3d1db5afe02e43ed2fbaf6c1f9f03c5936681da066197c12315e6ae39bb2062e26f88ac2a47ae578a675986db8be4c75dc74b46354e5090696f8529a10595fe8be55e93b8d5d8a15a2a084b98efe05c7773918f6fbd753b057d60fdd55795f97e99d073f1f160ef00ca0ba44386d2b3237c1476a05a233f046085ba0db4b85b8fad248197607bfc309e123c9dcfd98483f1e79709be727f294feb2424c1eb5f3a2733b8ff07d8dde0832cd672da1c26abfb6f30d6190e26d1e995a94314be69e10bc7755debad7272af3d3eadafc969fb2bd05d929f58ffde6af686baf0bbc19ac70979254dea0cb7f33b732bad38de402a0eb55e094d15687be601f81f91c30d85ea8e909097cb07bae067ce08b44424d4af623abe97c9e1f9bfab5c045db5a01431ef4b1858bc0ddac9c297d59d1a35bbece0adb7834f934677206e7b80cd0518b540c5a2d7bac0fe919cf8af5e75133b950afd74cd4693461f936c80755d928c6179a10e2f49f64d08b26ac397a517b7e3ac872058b944de963f77c8f76ae3d1bf7fb7d5317390e4efd6978765b7d9cdbd440c3b72f746d6199cc69fb560420b273f71da931c0257247e9cc9e149289af96982ee9342b2a3af365f25d1301326b707c51c42f374ebac2baa22bf1fe7f6a2ab58e8fd1f919bed31694f27ddd5d05f15af86a66987ad43170dbb8d0ae16a9ba69c3d66a3661e22d04bbb005cd954baceb409e1546792a94c2061fdecca24ba84825be50f0b66c3e7b208245b58413c0accfdf11c932c1486e6c3ffd32a40fda28cd432015dc5f88e223a003e9da6fc3b4ab2e8e4fd673d012fc8574f91f61a3b2f1a3e1a44e97b059d615b6675c9d348ce9a2f60e2aadaa85f8e8e9eb932b9132d98730aae2105d7c582150464de42cd124d18e4b1d00dbe2d7b37e7481a0da06175e06dae95d2453b7f212f1ef4d39e788e9cd793870fdc8e1dc92a629e28310bb17671864f2685758b395ef59daaddf9166ae26a6b5ddbff5cf9d143595fb15eda80410806ef84473879724a47a98cb26ac2204d82374a14434593f891836b36508df8d33a451ca58bccbedf623cb6e1278c9ef87a7a059c72e1788c93ab5638b6fdd191a4fe24c2ae4b1c4478450fc3918783b722b5b635f5e62c181d104d7c6b24909e3dae64c0459117169a863ee5ac339d36704c3e1ba89f382f5a1862c216743656a4ba2991aff465d45c8491a9197f896c3b1bd9e983a26101e731774419a88f708d9850ae51bb873da89d90b3516ae8253d57f5e52c90849fd43daef8e22813aeccd2e3deda9c1f26e6bf9fe9ca71909b5b497295dd533cf5860f60b658d86d1d161ee433a78bfeafda9a0288825c67f5c114a24039ee9e75c02c1647eb1b5c8d55fb6da6a7a925c0cfa5c8cac6c6af9ee497f3d2d55f88fb65e06b9da1683667b2406accc3c0fcd661db01751b5dc9b9d02ea5243c263119b0c1da03c36d98dbb42f104f71c5526124573f63c4df07f50a813e12c33a255c1b3e79987606d79af390ac6ab48addcee62a89cf66192d09631c34892ee44251e1189c75ac6b4daeb9d5c7671733fd52a99ca0ea0b89dbbdd6125e250c0d8c5b777b7eb51a9547ef7c3d83060fdcb5939a510dd9299ee48c95044eca09588fa445372355ed14bd84311219448b3d8f575c94c3d9d91617effc0c23089a571257439f0bd51c73e2ae5f635ff7ae3b9446416612a614992c718bde4596806b75109109a1731e1ec416c6992a520622de9e14e756cb1cb5b4e98155994892045a462619d9a9f6e3ae4e2c506ebdb5eaec68a7927a72ed27bbd2b84281e00b12528855664793f41ee75fe1424d3fce2c3be4323c35fa1a76c546cafeee4863c5d59e2d45a707a3127588d0ed59eda47841865f87ecc6bef0af952de32c5f6f68f0c9ae3dd78eb0bb9662844444dec84ba295be742062ec1f602332022e2e77ff0d214caa4ffe3548944b83a7310cc882e360b110e7a76167d6a41ad356ff68f62c7912b1540d2cd35142518f5bb0b66aada4fdd524cb056db7fda0ea3e2b86139942993e6a8b01733c0f81f91a863c9da4e98830dc12eee9c19bf02ac8771668e56bf3d6de66bb8381a90c913e9797ecc444a554a2dbffdc34f01db79af40f2d81318dab7f3c7bf1965167333f62c63b8ba9ec61fda4c32c0f13eb8a1ac97e99d2bc65d4a44cb23e9251592136a2d451b1584da900dfafe68ad462c0b993fb907a68938033216b8afd2f17a1d26619cdbaf1187e64fe46e4356e0bde03c8ca6ae4cc1697723f1c199d367e588010dbdd34ad702c0dff21595fe71208fddc30d0752a425a1d95844e6ebb26ec85e648eff348393ea6308730b472974191fb78dfe2cb43edfcc6f2fc6e67f2521c917d9921811f702855e8ac85a4ccbb5ecc59b6394ac2148147a5a6c6c44e56adee6a1d11f3d607eceb235a58a6e44ccbca793ec354172d8b22cad3efcfde87ee14c5fc42e8702071ae9098e8c59967470600fd2a5e96a714fca8dd4f0a8ac7d7bd1bf1260f706d3d08296e2873d579052598e89ff2fb5cef1576012ae6697956e27e6209b9aa2921d03b42cbfd3adf120dd7dced9731bb8bb36bb58cf89b4c5819359716a2305e01489e573ee97d9da1bf28f8d3ab7c6288c843e2c5b2633e4b7b4416c41671e1c4c0bf96127395b88bb0bcd71021f233e40e7e689496c640b12a038e3b61eedad9ae7635bbd6447ae4eeec9a25ccaf7a203939d635807dc879dd0f2fab64a3000dee7dccfd2397e4450bccc2ead97a4dcd4d44127a267fbad574a6db0005ffd12da57fe4166bfe4d35bc95c3d4318bb5506711174bbdb80ea8fff2f3c416cdbdfc3e0d3554345569fee25ce55208940372b68c8dd990e54938b94cfd1383f3e6ccfcd2dcac807516d74d72417f78f2f2ab8f27b2f6a6293f12d8967338ad8a9abd8e5a227c74a61601f9c25d562169a0d8ab90622d2d69ac03a8bdded7ad09fc3368c02388eef90c4706e68063e4911f391aea74c980bb6a51c3cd4129f0fc32ec1560838dd9256633c29895c84f00e07e6007729758a16e90a58ae1707eb374016c4060e3603a64a659cdda4eb416d66e70f75b5d453f16d6e4f822a93687f4bd5a1f5899ceb4efe7b558180b2809a8cf39d8f365adf6938cd65a00e742292233375d6c68198ea03d5e810e5c706305fbdd47f8e3eddf6422abe130d9a2165028958c1278deda56aa9b0eb84e6fc5a775daef91a9aac09e9f1650056741d9b51366cbb0bf8282dccf4f7570f40a3f465f964d3dd9ac7ea2695a86bff7d6781d1debec4f71561b5af59a8e54e018c45668b5b09bce665b541d9daa5c028c5150e96004386ad3bb672d7679c6013a58239f1977a23cf82d3d2bf8b38551e6b31182baa46c3d86c02b1dc2397df88668c93d35f7e141718ceddb704a12eb280d34a9438ce02f316a20581ff20c17f6adcd2ff3127097614995575bd0f56b61342e3ea7ca2ee1ce3861a8428e5af8f5081a6d2fb6a7ad7b902226c75ced2e18cddee3d16dbac46ece06b727c9c4f57541ffae017fe98c527d8ea25e76b11bf3d0244c9e989e2d9f1487ffb6b06faed243bb7da672856e636a0680f956999d6784a62d50f635be493e6090f24e2479ad990571507c97a257e63bc675befb32d5da333783a6bbad07c545e469d7d71d6865d905bd34ca92ca4cd692fc99d7367aab0107933fe71afe059b36816622447c67dbd24eb3496d2210e593d7a6112cad2c5f240aced736109931d259357ad91d8d85a691c032971fddf454e70448875206a3bc321f3d65d2a4058680153685e1158298798d0755ab4a991ca225518fc4bc8cccda8a0ac2759280939b6a71202e78f2548291c301fe97936d7776e9c77ee3180d1ae1d9db26d35f0de35a5330991f1c67a49d96ffbda816d97d8877d1bd695db00c3546477c1f8124a592a2997da1cdfcc8d1162fb5d6b7298f7f47441e689a113ca231cbe8561898bd7ad7d0ac1206e811ec5aa7346c7a847e4f906c5b0c354d36564cf65f699ecfc45ff9be5493ea37909519d2d0d0dabd0600ed34bc8227cde2d2692bcfdfad32da5dcdaea77678cdab663784eb2997ba9b9936a5abb62f4b980fffc34055cd8fe659e4878e5b00c4e168f4f1bf6398d2d53228e9d8a03d9c3062d6adb90e9eb8f652e089401c0e05008f1b37e259e601adc267e9b61e2ed83162b3c32f49bb5e4d580e2ba9fb83627d4b8136c2d2320d41888e21db2b57e520063b6823bce7aa9312f120ded0a9d860939a7d911fb833a8b6dc0608ab711c9e35edae7f0662159ec8e3594cfc769c59c65ff7c0c9bc29f6287b3f3b100073fa02051f64948244c2662b2124bf181c12f7bacb7729c610889cf5119dd1b967a22da09e6733a0c07a9a1d294dcee5015285cff22de58fa992ea9125f7f7d2a49ff103679ac3efc3333913dff94a3963e92983446a3ad126d9cf199686b5e2a572580627d78a94f184563178daeed94e21945789e4599eee4e62d7d7088105ab44b52fb6ca528e39ecd3fa7128b2ee9791907ce26df56f54a0f02a19eab9c0037758aca9f23607823c13a8fa2454311481d2efc4eeaed02656064ca66e1ff48bf79b0add93d741a3c98dbea2d0e299705b6b9c7063d675ff046ed96caa545c69f76e2769a0abc30c61c10ceb932d761ad754db0e88edf2846ff2bd33200ba14ff644fa2d2a6667f583d4225a8a37bc5899c5d86e88786b2014fc0f50bd9a5eae1163c8f2fcb4e6f1968620e0e4512ca4b33b84ca6da636a796de851070c8f92c9d0e7fb09d3e444a6b8a464168d1277e45d3eb03e283ac9a7cf9af0bc42e93feb3da5f746a3ae0278b5e5df6c812e97f3078606f36e3f1e4042b0e8cee8ee249ec90a93de5983f9892475ddbe668a2b0f2dec65b34099c1cedcb364ce78e2d7efed9165efd1bcad5dd3e190d6a199870742f20668fb8e799d043ae49289a6fbd042f6efd8c1c735562fa60688973bdd2abe52265eb4007b202b0366f7a86f2aa0cfd1bd6ce518681a95f69f44a048900ad4043a1d7e2693336d728461905c5b32e6e644461abcd425d58ce9cd37861c5dc4a08d82e06327444e4b229be47a7250289fcc438defdc5e6b7d72914d42ae3c7a2024df3024038be020ea35b33b1e15fd01b06a4f9e4bf0c31424ec48bf6d763dba0cbdb7d9fc35a7a7e092dc27702c14c8944c584dd8c3a87646587f247ff37490279a9f9c34a08d922913a235cbe889b0b611e4863d19a0487d241930057ee538593474616973e36247013430f7aeb5f7f354ff5e7dfc0473c8028b6219760fca7147c5cdb6dd33c1618e08872029f5576c04ca3ab618e76ab93a479682066a47a3a079b1e68edf4e079d79a65d0639ef1b4b3d3f84d66776608cdaf59ebd4070bdeff845af4bb86e353de467ec02a08515b8d5437bd9dece05429b99f87a30bd68e86041d02568ad754a40800f64aa601fd21fde4df2943df8d97eaeaaa5213b1f0856397ac28b22022511e27de0c0485851983772dcbd9ffc799abe12f2df8edd2c9dac8f61d8e9aebc97ead5302861091117fa73cbf21f7703918e3ed36e6dc76e540fd4f7b08b22f033180dcf1f63b398c9e46cf0ec66597a4d3f4002eee929c1230ff6bcaa52dbac861b00cdee62c2e1e1adf12a2f9e6770e896acc614725ce72ce8205ed24282f9ea269714f2d43c750780754bf9be6e752015ce4a2a537127b6a889bd18c92a91ac174336a6342e8a4d20e44175db43db9216df547f86d9f2ba599575bb57725a5c172fac48db01f1b68eed86c7585d4efd0132d3f85e9f98e8ff15a23210dddcc18417e62a70fad860bf024b5cb6a2784774b75a3c146a3eb1a8c7929d3cbc69d2f5e7c285b9023177b617f9c43d54ecec6e21543b3b71487f21986f472886d316a24a5786aefa6484107a7388bd8a56746fdde8923f82a1a3263ca259ca1936b9bec7f6f1cb226266459c1f2c51d58a9342a7efb7efc01c7092fbc78a254803223e18a31018d33c69cc6a79652576d833242958f46e312bfbb97dcd1204d07b07c3384cf3d2d675f6acb5518c90a88dee145c6083a9d77a4f895763a5b2a9ac04101e8254d76b07453df781c45d0d5f4085146f635deb950ce3adee734dbd2064ef5b12aee30b948f2e7286fa20020c5801e841bbd5e6025ef55fb4069b2ae96097c9b18b1a3a68c6283b3c736fc96861b7bfd3e26cba71d4e81feba5f6920b48779c4a8e68e452cd6261682176acf177addff33b5111ce3b97757892751480f76c87b13d1e899e2630c18f038a932692ce79504ce10963fd66a29356196187641511f71fe025956c603759b8ed092bcfc21a67f19a2d36add048cc056b217d4d79a53b5ed622ef837b346af08f494b26fd51e8dbf0b1fab2dcbb76a637b42a4752196b67ce99f5e141dfa90225061db83d4c26e1211c7eeb66ab0a37c101ac5271198285cb32fe71e33f35b7070a37c41cea016cb8c8a933bc5d568cb25d0a5123d0b317d554672576d12f80fc9b3111158d50f13ae595aefab29795d7b9466a0922dca5b172a3581a7a3c17dfba447938fe6df63c57082fe151745306f398a657cd9604c84346899fb3f2f8751d52935e3b27f4ab325c5ca64d31ff1e40d98bbfcfe0a2fa933a345a0843bc8c1fa44f2712b7c3d89e11695769025da5cf5160551f8773690a415a2397519c042303394892ba30a72cbe5ed0b254c7814d018d3b857c27eb50aad6800ffca3e7688aed0bcafd5d888a5ea983dbcacbf7ea41b5513e77e9545f39c1aa1c6ca065dec8dfb730bdf801b71615f8327c13772d859f91e6c0d630daa3ae6a9d55513c2febf76f5307d7921fe82e9abb9c053d59fc06b1a99d368fc86b0b7ff53f9d7ca841d5a69f3e61ceab1669dd2a7595a1083163ac69c1d644a36f009bf80ea243d9527f92d70500aff6b0751e5f8068ae8843a9a79851442307d396e3ce98312f9dd5969c0d20baae956fd7582b188f6cd7a832fc7d4b361c5ea0171c9fa52e39513f07a010c3c08080d2fc61b24a99fcc4b4d1aed608c3fadf6420d1f167912b038058a4ea19333daff3cf2be62904ea25c2843beb5489a58e19f1efecf823682fc4e4bf22e8cd8dcd36fc5dc02f1e94e329d9b5338ea8c3b909ec6e5dc87c74ca0aea834a9d96738099bf7cd8063b650d57f23f15498c783de844de2cadbe6bf1e8b71e7939d6d0f7be2283af91358c9f926336c649d1\n");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSLHDSARandomPrehashSigSHA2()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("HASH-SLH-DSA", "BC");

        sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")));

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();
        byte[] expected = Hex.decode("72a4799428388928769dbdb7dbbedb13af074fef161d92b7ce2f88c9e46a20b51511c8db0a9fbfe2100f34d6e150e55662992a2e3e5a7c735964dd23ebf1d3eada66a9d241741675d04cd5c780bab20c5c2c1956fef96dbd693d16ed10c416c2ec059d6473f74e7ae56e97cad4b9c4fcd97da8b6cc6962b82bfffbeff63c5d1103781cfe64fef3fa1df924c08e971028cedfd6e4d00da72566287aeb4b31d40e99d67f97e4592dbe3ccf37d2d9178e4598180d8dd16a9a033c320c0aa52ffe4ab224c1a71e0b85c117a781b082bdd42b6cb16e8256e0c1310879b989498300f4cf6cfda4a0ab4584a55926e80074994e1ae3da53951361d1a4eb2d19c8348481e759c172f195a36a87dcc6a7aec73884c425fec37ae54a0fb8e624a14c08efc4c4d19d981d0dc0fc8e3d4f70eed9bfd1935ca393d862678c94d3eedf19b6dafd68213923bb079cfa78be9e0ae57bcda8a4a374ebb8129d2cbe138c7569c15785160ca1ba46ad8c22cadd2092ad8889cf0d5775865c16beab09cd0c9f5bd2326a9e2560f0c910dbced2382d7d1b76a6db20c10354080015fc8f43ac4c174758fbd5d6c4514d496890b7f5971cc10d8c53875f2e594f7accd8b0970dff287c4d6ae582f9099cfd765ba52260cfd0ee1058e53296f006dfd0f651d3cb61426b94365041298a78715911b4128149b6078a56587f2ffceb3c80468d7e5e701e4f664751793dcc08027757bb0bc71cde085677394556aefaa3414bcfa30c3142ea1da8320e2840bc810bf6feb378a502ead4e6c5decdb184d0204839a13e0a75bbc73001a99026bf6ab2a76a5b61c9ae59397cb9e0e0c72565a45e000b0d542380db5fb416953dd224dd6dda4a10b6802e58711f7aa3f52acbdc087989f268f8faff587231206aaab34fadf678c5074ae7bd102b9cb7a702fa5e59c71e732bb3a94eb106f6ad00dbed23ac53d412bcc12dc6da48a4c8ca702929b70d1b3c72fa0ef5bb74a7d4e4b6e1d88cc5fd021e4ae565081db628a7a3c19aefb66f16e13c97347a88299438fae4ad4d468e5867dde36decf65a7b2d8503edde00e29a81c59fa7666ec570a0230fc72523e6337f29e9e32a8ca230a25a410461d4c83072c962e75a1aa06717d664055b361b985bfc5b44a724174d918d11378b8cb2e1f147d07e92ed740bac496d24889490d3323bca1d0b16e85e6e64c910051238118818d61bf57e6f7ee583490414160694d6cff2f36e8273f91de204067dab58ddcf63861483cdb42bb7288df5c0ace9c8687541468fa0f8e4227c1185b2cee47f5e9cb30243d120a586d7d2be69dd3bdad34d40591ad0d66f23c093d8ba6d602aced5fefe97a40f7fd3a4b7c9d573cd76fef2fbe91c7d9cb1501ea4ab4653751f594ef2fa25abdb7c8fb5f18b08a79d27253afc7d982aee4cb8b9d934e2f4c54721eed2209edc98322c0b2a037f4cf8f2dd770a49133c0b4d1286c992a3e90889860d2b7cfb86a56fad5acd0a88b303463f1092c99112f172179fb2cb8ca248b2566bfb3e9e6c248aeeef6f2960aa2cf19f90886bdece8ee79d5748fed875d6803f52dbf2439aecd9d57fc1ebcb2bda048489f22bd6ff1c030c7962c9f0f24fccd7c932b4ff04fdeed057eb10f056c10bb953131d7fdddd57a67a0636b91f3ab555979eaa1f147063ff96d941a8db4c6f3207aa99154d39738df179a5cf9ff3e04890f6db1d5539a133cd4fdb227776129bd0a66586ebabfb72b8711f2deca806e053dc48f85052ca53480df5d76f190ceb4c861906695179542e7676827409db96d5db18ed9b516a6d402e28769af8f370ae79eb3bd8ee49abddf1c73be955db0018095297ec8b1dbf362c060064d1ada557c9d5069e6a2e7fb3e4a254c3d19d34793cb37fc64a84ffb4074f97154144a3bd438757bec1875382cb8f267e35406f582adf401362dcfe0377d53afc703f2103c9a2ca8b679919cfe106c500b9956a6397901690e872cc3cc33e5ecb801025e66d5cff94a7cfefc346b8190a19359d00907b48e128297f62ba3724d8da7280ab5bd8f622c9774fca979aef429a83d960282223bcabb7126fecd6f9f40042e23dbf6839c6f8889923f548ecff4cd2c355ed925c3ca3a30c523ada85df9cbb1e2136167fb5729965e2ba28f56c3b3ee1892268f549421563386671bddfd79fed9f16b78b30c7bafb1f1c58d9b3ac9f2f4c0873fdbd29e66c95106b37da1ccc5db9fe1012793fc665fb61e9fbf4013293b34a5ebe1cc38d86c9d0efabfa4d37fcdb9fa634be8e73d978c234721cf1280e178c518f95a319f0eec550d4c1dc7eec48be2735cc3fbdb371944e3a7ad1c63b227728e20d36f9d99356e6cc8eeadcb6a5a1902712479c2caed16949c29c6b6b09cd4308e1243c0531a9f5f4e7df6a3d27e3804fb1eade52f61131b2662ca60d9554337288da028584c90d33ba54bd819f75555ffe8e52f3947cd9d3ccd564b4966ee41cf5c7e012f7c36da9b6899a9a65ad88028620568ee049128f43d75c7d25436c4d0d95d1e6a65b781d2607cd1f7096ccf786808e2aa01bc6351cd3d526d68e226ca78295b295bd57ea1dea943ca06d2009d749001c46f4bbe4006b9a9d2361acda0e1546019e652db6c687c7fc94b6d169924d8327e4bb50cd0abbd249bab3906f292659e869f988f0565df5798bbf13f0ac688b61da2253f44f588dba65e33f07fffbed7ff537a27db1370c20c6b136eea20b831048ebdb9552753f6f7df7e96ca6c3b3cd1cd202b9d465bb432d70564124742833545b52e8022e93efc05f8bf85b59408779b938bea0caade08f19ed6f2702adec5d9754e0b4035baf4c927420121bf9144fd1953c5c9a2f10b6760ceabfbf868b566eda0d4da954b0707bfea2a671362ff29866422357058f8d676051abf106911a0f728ea42f0808fc33804696cd545449e79a17785c1b0fcbc552cabb3a47eb62f63678f94ca4426736316baf19c206fd99e2336c3b6ce71ca381cba83354b3343ef28afe87983c6c5f4e17d28cd741284ef290767a224d2995023ebb30c50d7a2f24d780fbdc03651a166b7839a472d5e828002764b1768add4b170d978141b8ca2f06b594fe41bb887ecd599fea0dbd36d74ebb739f0c33c51116fa507ccd3acf415fead7eefde45c9359baeb18727e79961bb14e12b48d4573588607c88a608cb9f5883b6f795ab8668b10d202decf02d353ba14287c3fb8db66b44b0c4cf74ea09efdda6b7b7765011cac3f9b46fcdedd09bd0e83a0b61ca82dae52bbaeaf28303f6390759a876f67eb2cd9c625422d5f0527c3199457084a2b20388762f45f42b4ad0a5d0906839c9bd8f01098ddd439f083117066c76cc0006e38c349986ee828170587836149432bdad52c959b1082118ae6cdcdf72ead7ca04b6fba03feb9581f5418e3d01826073d46da8dcaaca85542a57f1a354c140c276e05acebd3e0a0d5b35a510664f431cb15586f496f5caa630336ce0f4f68bfcfd04bacd8ce0d9e9373de3cc07c0bba21a237bbf95030b422cb59732cce8eccd56ab533aa078762f4f76b74d94ef1b71d41dbf388095eb38f34016488cf568c3372dce84cac53caef7a5358d7d21d90007755e755bec2ce744405d253a41e51683d33eeed58d7f96db807040093064700fa298b9d92e86556ea263d7b1513c14b0b6558cfde6bba6db7c1576b6ef42db41ab279e197a039249adfa8c035b032f0c213c40f408883b21e55152c8e1bce8d779810251f2cde1b1aa955fcdcaf61a73d024972e6f9d9bc1f90b05e122e09e35ace70f1c89309a0f53b465a3d1dc14bc77a01a323ab53756ad864646d9cb128f54dbac67dad6cfbb9abb23beb7c2c97a7ede7de8ce5aadd97fcf5aa3b4bc8e7f51cce2fa1774155993ca7e95b5d9275c432163b59401df8a140e6ec5899847cf1fa486c53832d24765c3aae4836af8818f3dd91e23f57edd4b640283e0ea7b148570379634f46d60274c33ca586003ebbd7f051852722e38b10bfeccf9d2f45035997bc8b77657c801840b623c90e82da39b64fbdc940539ce5dcf1d6baea9cca0a730896f3d471558635106f1c8bc8d881042bd4cc772e9587b416fe2aaa8355d95f44342d8a7ecff2d94de3a3eb5726d21045bf2293f24159e7757dec895ce05de5932323708257a0a0b6230285126f779f8f793dfb7a325609ae993ef030b3b1bf32860313b8636a2ed42c86c79875c28f998b4a56f1a2b3554b82c60e2fedf499f28a009b17a10fe543980f0fa26b04361e080acdd2be6f538faf483ea870c37979ac8ccc2e1cfa13a36ba3df754236c60c77fba4592508b8b171a0f12589d8a91014dd3c15d4c494337c094bb4d19da70ada22e282ab2220c9740c9e360a44cb6729688c78d384f3beea925223a5e53ad2bca88451587adb8f74025a208640de93d12ceee8ea2b5e02a8609f08e4438923e04c962d0fa5fce38f9be6901dc48f8c0ff12095f27a416d365ad0cd79d01748ff4bf8230129265fa2fb845bd2b794375973c74a7b36c4ca8165faeea2147852580751804b11c0072eb305681411f9777462b76f6ad66522763952db367b3593376b2760564ce828cd6fb6079374a6feeaaa3132b99874110c2fb7582a55af37aafcb7bc30ee10d5376c19a4e41bcb03b571ada34e203d726610420705159e929443aaf86b6956abd938ed6f92879a9e55751f37737363be0781818ee4129fe98917b67b369c083eb829d7be5734a15d8241da90e9a6b1a903e412a6013743d6601838874cfc61a5123086a6cbb74e1084c09b02b370cbfb41a9657c267a1b96ef3542650adf6f89c4beaee88105d44790449e7921766f28d1614f9ae367f7b145a145df4545626ef7642bfd41539006f0febccafc3d78f9366fa4f8e6ab7623fd71fa8b2f429bcd44411046b1a259af3234015deb46c2affb0f171f7be8d93bd0e22790cd7f1f71a91788b4ade58b618461b9230827a7b786e4dd0c5161845cbe76e8eafa2d220818e8cedb8d7b331c6edfc8044948f55d3dff7c6683fb4c557e5d28f9bd89fa149e6b2fb6b97687ca8f3db1b54739833a155344eccbfbca5c9877d443c31c7b64057f527dcb025ac76ba663482f78430ffa561cb7daee7ea4c57fe2369e03289bc2f3cd00fea78afe92d12535a0da39c878741b139aaa3145b512a212076fb16d3b981d71c3468b5e423454e2dfe97379d1463a657473c75ab70802c5e74d32aaab5f484d426bb4c5e04cc7a90e3fc6032877ba7d1dfab929645a2ef3455597623b7070c1d1c0e911da3fb6d867cc039922951642f146c2edeb57642b8cba633c4c7307b63933c8cbba3287b10e3f19c154323b7e0bbce9dad800c272a345195d5b9aa1085d9ceb4748c9bd9af98ba46baa3793e7c11e41d7306eda0470340399cc5e420798ccd8c482b104dfa597f8f164e3596f9a0f453351b328ace8953c7d41d9dd7b1c8207eb3815b954cf98a7b5cb56eb0bdd00bb62c4fe4853b30ad580297cf5f6897607f69cc0a18348c00aa1942c4d255bdd451ec30d9138235eaf757bcc61ddac4b9098cf0f95fa3fca9d2a5c302907c708284cb1923d74f1d59e5d121dd4b35a38489be9ffe9490d5909d2343b1c5fdd373e9bca5cb4ae90963084b84736ddf4c45151dfbe6172ab5b9bd0b75acc98692c627395c43af4fe4f6d71c3ddbdc627bbfb93af98dc5afec9f0dfe57692edb63bdc8d3a8b553c6deb11a8c746e232a01c79abedd64cf5eb758a04ea39901487af5d91a96f902e3ea34cea70cc83b1fef260fbd1b0c2e2f07a933b8c3202974fd5250e77d160d43de98810546bd77626e2954b4c2c39d10592e8bc980ce338de74eca85572bbe0d7acd2cbcc00d6f1bba9fcdcd5ec42e0bdfa06a96e2b87954f3091bcddde09ab84278ac0bc7d8b484c311b09bec09618d2fb0e7cb8cc5470f6e8937da5e2138b473fac822ca395fbabb45e75ae48c2d5c815eaf29780ef8268d7456a17ecb05ad2ae264f8cba18d783f75f5f044ab6430647f7a12a3afbeeb034ac30940c0d22e8b5b5890e08e2932e667fac258e8e75b85b2c8e81eac0985bd75e2c3c69c1646bb503924acadb155d9fe0f22a202cbb18aa660d20aa1646757aa8192cddbcde86dbe53768023dae14ee3adf7d13e0e484935915b799deb0f4dad6b898d217afa64a4c24fbf351f96f95dd35a441d5497f8f9c404c13044f769d1a15d32099943211d8f952ac341840e37426082e0ef45050a484ac31ca6d9de7df4020a7c3d3028167ee321bd76504b4bdbdfda582e0698bdd056e6d242c944de11d922891f69ff4a835a3b0dde69c0fa2c03c31d3f02b145f151f40b466b89560c9d36e4d005dba3ad6c175052d6c0edeab9e9ae6bcea00a47e954f24726e1a16e42159f83b819c02af027fb7603d36d3e3469ac4db2905f22d7a6970e8a578928a38b9142e3bb4f21d1415ee4cac1ae263ebc15fe984c0b465ca9920aa1874460a3a69c07b9c1f9c190867b26c13b7acd305e53b20873d1c2a871ec472fe4fd9f1892c999d48ee7fb71052253ddcb6430edbd25e52ee414542b225ec74fe6a6982d12520073c161012aec6253f9e13161258900d1146be6364513cf19cbfedad5b92be163221fedfa2a7edf4f4b7d204f7dc3320fa2ac8543c60f8c24299f83f81e0533cf067d685e1e91b982eff8944f7ebd9f47075669a51d947c1bfdc6aeb6c23a5b9e7b25a3fe14f98f026a528183a61751f5fe0af4029c98688993a2d3f09885f89f45d5aff9901b20354229aa5dcb6b3dbf7c92bd1134d595f0a646a6e43e7ad60e468a580f3b9c9b1fb10d08de00b09606b7e7f4303c7e4a1f3f81a3f7dcf06c9ed9a67ed334d127c976e13dc8208543e50449a51364860b16066e9a818ec64c6a9f4c96d4da7a74ffdcd47c051d37d0c0efeb8ef4797892b3b6c73d0ee5b75b82a1fa3015ec364196efcf50646689630d2e2c22d10371ccfe5d16d68fc2554e0f6a476e39091447858b9da17d31159402808f652cfb198331d638353f3ed4a5cac668c6026184846adeb5e9e78b6c792e631f445a99857943e20f34898813f031eadb9bce1c05c4bd91353c61d20c027729a6a94794a387cceaec7c9a5d44ab2d8aaeb1345505cd2ce2b4f29b85345b5acfa8f67ae13e42e88af788f9d137abd13dfee0e9b370db1bd231e4316f9553514a1a6f414d4e865a4b5363979b743fe1e41a4664017c8715b9f51979b78d232d12088a5eb0abab89a444998618e9cd1beaa16f71c1916139a3ba497a166bd4095fbfa9a3c308ba3b218827077e57700945e5a2689484444cb354be82040113f9720109609494c4689be664a6e35663066500fad77638b43852f1d3df1682b235dc96ca18e3b135cf37f71d0da7b412752408f63089850b84e6c410dfba271c75d0d7bd5e4a9a1876a985a9d57365d3b7005c4f4c4182515d80e09266245227c0705d798023d6d160f7ab3373ccccaa2a84963cb6239479b8c3601b7f25432c96d8972b9ef039516aeae59a4bb7c58ba7c21c439f0c696f35a5e673f877eecf1979a8548b69351647e196e7bd6b1284bc63c6c85d4a7f40a49778bfaeea4dd3e5ec7896d26012f56c66bf26febb0a2bc451f1c87bb75f50c2a69bc13f760d87e54e8ab62b917ef6b5efc7de4b98ddccf53d984f4163efad04637559110ee6bef2cc96545d0e15c5b59a13cd217d2dc9964a0d8c9b36578baf19f4b06a97fd5bcede1ddc10c9e2955bcbcc6eb5e428a79c3c179c8d077933058406d433256e5af8ae6bf91d017933d72f07d661070af6239bbe996324f6be13e376f8390dcae4cecbd04c5ef1d5d478d5a2cf2da28e0f917e10134c31bfb555f91979eb52d637f4ada3895e303176e91c096d5f4d0175c0311bafb47e5ebd6fd6c985b4baa9c7193192bd5b0d1c9918260f6925349658e22b5131e76eafe769d5f9c7a993fede1eabff88455e2881d066092289ecdc1539012d74e9a779ad2068a3de66ae91921b51683f5a429d9a3b74d964ddc1e6cf89f87f4945cf8dd0a40aeee254592bb56d01ef27880084e62022f73d6218e3db5cdbbe8e263b8386e2112682e8f4f5abeb85d00adc8ecd2aca68183dba492facf3aca9d99f094c839c276e59dd171c9d739757a0c4458796968b00350ee869ff4c4eb4617c9f08c9281f7b860dfab10e259512163834263ef7c5fee091545b11463846e5e8c9eb61ee5325ad8f826c39dd4cd6d99f6632349e1a3b5f61f55ec6da6589fbdac678cb0fac1b59e0167718daa19d70f53687501a57e878bdb34143c6c0f60c5ad3f3c733bef05ae3db4c739730bffa3d0e1a636f6045742faa409bb120feb724c9ca7d9970f93075ba3d08845fefe0a0c9608e4804b9a7947dc96b73a981db5fbabcb11065b6e3bb8f8e86f46e8e9fbde3be3af075dce460067c61d8f2900754c19377bbd665ac9d5b479ae6ab2cac510f633c471c7b332bbeaf948c66c61b9002b1743c351a5ab1774ce05e6a3d83ac64d6867fead6409d75caaed8173d039dad33d39d5d6df6b7b7182669028accac0c345f4d3cb25bf6b8770080400a319bd59b205c61e226ee17caf61d1072c8c03db76ce62eccad476c9d46b4a458706062fee5b2a3224aad56b504c7dcb595e77f25a69bdb51d39cd7f8c47838f3e6de35fc1e4f95d50e0aded698010d4adf01f0d6e741bb437fce1f7530321c104f8983c59e6bf368c7051a4c52a2be813ee22d1c0555627cf1e28984c5fc684df7eef4b1cf71a336fe0f76931407790737f2660226dcecb200bd25b758b223a58b131cd8d8dea8befc510e02ef66c891ab94b80460f0f830cd7b93aeec505f373683723961b829e1789bb3ecc10650b8cd473949f2a0b4c155dca402f49c3716e2abb0b719aec4b97833dc908edfbc410f0984cc5357512c7627fe746fcc685654c029b5526f6242563922c4ba74bfdf34942f4edcf617021f6cbe5643e2aae94435d002b85a2d4bf3e83a2ca2876d796e3ee5c4da576dffb13de1fa6b34af8468747886991a2627772fd7671771f898e9f608d1bf754493c974084ff92df365e209da684bc4f619ca6dd17c6d2e7dc9b0f99519f1e185eadd672faa5f5cb4f5098547177dc4a1a21bd0772637a650b83637e80832be0f73533be7da7ceae4f15ff2c0e8da421a30c8aaa5d1fea84c6726af1fe2316526aff16919ece6881f116231236bb3d0cf572e0165048beb4b891b5f80cb45d89ba5d4b49c5875ba92536d94e3631a7a66e2ad3e192eff3ec26a5bc429130408409a3421af6fda7e7b00f69d16448eb4ed77cb45755966a86ce84e6e68956bc609252378a59439b9031d6584f3fbbe934ef1f434bb927efb59c94c2a5c2a05986bddcfc18fbb2158195870ef4979faa15231259eeb753e7553fa6f25581e030132133473c02f158855dd773365ee206ea2272e332a081ddc9e516c85184455d868d51091187519b2916a06b6f6cae3273f0acc27fad3fcb0021cead95815c217bca53b0159f5de3f8dd8c5bf60ec90a8c3bef4525bb379cfe35704ad8b7dd476a1c8cd1bd012c2c44283e15f8219dc183addf3d82506cde22caa25f176663129a8810e10a9fd8f67517fb01a0bf9dc0ba80d622d0be058d4abb98eda0030ea66cf266ab6d3543623af9643faf50405247a5ccd28bd73d1a16cd4364651f22110203f82b56f6e09ae90c7e617f2105ee4e7bfc97a6e9b3e7704548bc50ab18aa55d17a7d779b911f35e7990b89b9b4f4b2c0afca9cdb771a11c33bb41708ab6a2c2c6b994db47199c8761e7d3ddeeddc72d11de9298819d03da09979cb9f42597c60b443272e47807f726ea956da41233f5b13e1bd5abb807b7f4bd3a31406a4aa68aa4823ce09f6f5560be40bff2f91b90db7b01c630adcdccbcd865de37f23f85384641d5706541a3e3d2ad586aeb0b8cec6f072e0e8dae4fd42359f95200994ea440a643ac03d3db077b8d4cdd52e34733b1702bd46659e0e8f89277a2c21216b0833ac896fbff381f9295b04121598f701c202105e6f1a0a135be0762f049d2286a9f759c4e6790010db957b4a4454daf0514c61611c273cf804d8ce8c6102399749cd8121b305524d5e602476147552cc1bed2f5b6cb352fc0689ae798374258f163b4ee362bca0a7081f3ce4b8bcffd582e94ca7595b49748963a1396d460d837b25b6834c0d3e08f2f2aa68009ce1e0fc95e902cfaaed492d86e44c0c8e30ac70e9c293b5e21a95a367535b9681f87f6c3119c1d70a8847d4e7fd2f9ae92d2606d2c9f460bf6e6f7b90caad8f3bb60358f345564b5ad4e72f416d3b6f2620ecd8e702d842402a535c23cef1252fa6462b77ac2299ee8d333fc67c038f686258de46cfa21664266745ce0559b66de5ef915ccf39ca8ca37b0e26bfcec1a000ea7d660584e763cc168bdbbce1566fc23ae02f51e9ed199e394cfe1dcaddb28037d12c80b929b8e10fd967e501b12cfc4f62a2ab2bd2cb271b48311db33f1c7675ffdf04a8ab90ff78bc6b898083a49ce65654a28f73bd3ac6548c864e8abc0c3215e3fba56c6ec2dc3a41bb147446b111531cc8e749e62101775d1e4b60f69944a3d5d478f3fc3dd261086b1e120f7acb92471a55c8de095e0bf2f598475524429f931341a800f0b0e8460eb736bc3904926f32ddebcde70cfc79b41629b0242860661c4713485a0abbc9ec982aa3aafc9983136065ba12494356c62d46d4f0d4bc979ba8d6aa01ea4f1b3c81ec367340cbc10097a46d4121ad44261afb1cbfbb297003c94499fb373267e383fc1eaa2b213397aaae7b5ad97b1e69b814db4a504f017903029f3725cca6b561c30a804c988d965add274346dd52fcee0cbd9155e7a1df8cd21242d17ebe3b1b69eda1873a6fe55e7403df3b7d6990ff0030dcd165677fe7f67ff433920568c2fcbc6e3491820a8f085fef06e5bfa973d3aedcb2699cb3633eafa46e4f9819acb2b53f6a132f7806b998274bb909274c4114c69da0765be349eae1aa93d6ceeb9f39b2f4ce0dd57bcbc867cc089edfbe167eafcb0465c4927466a254a6d5878a3f7ff6a50b7dc5c06b02d6e50b1257b450b1b29a6b8fa3bf33efbc83c75d8a5ceb176e155cad9e2f5e5e9c76be15e0030efc35b89a6f81406bddab46029c99976706bfe02cc4ef6e9bb7e9ad09540f18b87c9ce33b7c38b81c4e6bf283cd8e0bdea43fc43523eac569e9616f3e2dab7192e4357331b89abde231d63edc7a6a14b57c7462bf81cc9dd81f68cd0a7eaa421787bc1f1fd08cf56868bbcb6c9152c1852c04816a888ed884f1cb9157c530c0f16e9f1dbb32e17aba30b47784fc3adb8d17d195e924e332552dc3b63e38b12ed778b4c67f43cc07fa09ba07252e3daa0f380d982cde3bd77cec5f7b3e380791260b04389ff4f76d498d76b2f3e1d9d9d54c6bf3ee2360b65182e31dce97314137c9b8ac15270482fb44f9fd9acbd93c7eee67969106416c2569e5c89d9995560729fb7a9c053c9aac09466307969e8d69b2a155d8a299aec31dd51ab19f8a468871fd99b2a584beebe5bfd7d3ce3021dba608404d1738b8c15351ae55a31ff4fb7801e09034305a393d633f7f917ffc22f2020de1d08b734b36f64b41467c705994c113b360da3ccfe5deaa1f14c57a9a5988cc50f1c1a2e94b8f9d4d06f3e43d97ff72545193bc12b832ea89adcb318f1489df260d53eb73b957a84fb010cf9d3a8a3c9a0f74894dfc44cf2bd61843b30f3c4534bad2fc895e325ed5fb1b788ca268d3bdad7771e0bc7adab685a4f8a8bda2dd79bb0fd6784b4ec2fea5b1f89e5adb921d6e5b2cb910381e2af36427f3dbc9a5542903e66979d56f5fb8722b86deffb73580d41fb20c3faa9a74add06c57322238263e45e039dfe79198ffba8457ee80eb96cedca462e09abde0709c73a4f800673f2c0bc22f64d63b6dd1b3d88323d4d54d0c1879bb7dcf8730a6a7cf6c29245ec57978f0fdd884a924e6e2c7d0a0134fd2de6fd4d54399f2374ca50c7bb587a7becd7f6193277c3afd036b448b707be43e34c8a93ab3a1813247d82d003f661d5d8584d35b696117195a1a5469d433d51dbf9c91657f2ed2fc3785ee448901cd1ffafccf07b20f5e0965ef99966035753e65d0880f25f15724ee0cb0493e63a891bfd67becdd7476506ffd35d4754e30ca4a6604bde4aead8de63a86893e53bcd2acfbbebcb2b71fa4a9fb7fa2f594ec11ef8044d9b7e532425bc5d819db1e2c70a510f2f87733c51164cb60ddeadadb7397499cd923cc00cf21b3db68d2d8e4eba00cdc7e2685fc453d4d5307e926823e0a845bb3a52ea9e33ccc691a16dc4bd69955780b388bd3050a941aae559ae467ab1c4fbb3243287eee6cf7e8f6cc50c09f6496e7c726fc36bc7d76fd6322d8c33913ea7dba43fd531c5237ba0ef782acb44a5df3f80909dff5ff386ff237fd0841f6fb6ed6eb401384147159e8ce1ba9298eadc646f3caef66274b4608c0ddeac901ba6f69d7c62beffe2f9e84f747f0ccad068bd34855ee34e4b4a06305aefad021dd25969e4325f3c500d5fd61ac37a7949b68992782fea1f05de246f87a3a1b8ca0cfc5b1d60e395066792e390d64fe4bcab9e532dec19011340e583f3f6f269d21740640b8c7f5bee4fcdde09150e7a757045a07c3acb98f14b0cba67dd3e8723f085da88a2f041ef1637a3b4ed330e421a2fc5e7b1ec7dc93286e3a94f01b099653700e6c1a85acbcbf34ece89d1e936e67215ec20ffd9a11f05ec8951b37836d76789ddf7910053309dc757b2951eee611abab500089376f960d3f4ae02e76b8db2ce01946c29c94060b6b799e7a1d49576848c1b56768562ef28c4a9d4c27b2806cbb86c2db136d8d7a92514359fe97389cd2a53313e4daf77c2bd731b88e6f8c17197c77dcca3cb7ab5dac3142a94faf0b945ba11f76a997e5e2007a4dcc9c5e9f1aa1bd3bacca2c61997bcf578a80133f25df4dec5d3872ed7254121ebc3b1ed60e19daac51efe8cc7c98fec4517ee121d029abf6a9c5a2f5a2fabf1b3dca3d2b9cacdd0219e3f4751a74cc40d2c71e17b7b938922b138b42a3f7a2480b30b41e7a565b5b1357ed5fdfdf2b81fbf3cd005352505d6ec953035d0329be868c99fe134acd4d9f0389808f528f4487514b644750935918dcc132346acef4e5658ab22136461ff5cbb16242948e240e5576729829c6c4442a3ba43d3cd6d5ec21615e12164df113e7d4c6c9b2beb8903c6a9308ce27710f4eaffa9c5f11d5736d2896164767dc4e8607f43f99f30e633613db20f4c8981e7d2b86c893a35a6a3c025a46b52bc99ecb1881f0a1826a5c5841df8e2cfb3259d2e9df02835af40e24c9024aca3b9c4f5ebe3d93fbc255d9f11a7566bbdfe74d5fca68ae2a5ddeb84424f11d2dce4de3767adf8e01069292ba74c771c3091579a26a0812539ab4904f26ab0e4a8255abba061da54e5ee0770cd81f6543532bfcee414507253a3b59e29b1c850aa6399ea264fbb59491327132309d64f1f1033e6a71265ccaa143fc870f559f7c90d1c96f5c81eabad2408f7804f4b6b1db91240e48613e7944a36b0080ed1e719542b304d4347250d9035f847354c72023503b17429c78f7c122c456bc87bec88dc637246ad2673338593deab2a331752acb84586fd02648d95e8fb855ac231cc65f8cd6fa5b002b5903ba08fdf54a99d509f5f87fb6f76d4dbd3985b33f0b684611835f06e73031f64728dd07ee504ecf9fa7e6962509be844a5f55687029ab3a0bafc83293ced1d4afeb1992b8c726432557f0e81fdad7f7e9007f46dc79a4a6a8a14d2a5d34104bd7482f0942a90b4248ec9e4fbd94949fdabd8c106e88280b9d636c851a7ce0b3adb803c18c1aa5b80b33ba415be0a8300269eef2d2a5ecd11f882826b50c2b5f52961d84f6284066f5174cb6e3c8909ebb9b9af5b41ad52e0cbe6caeb19f13dda2da24b9c2f96cc58f712f0b8f8965369812fd8797c7e3bf0dc5cd35edc9f725693427febd0b1d935d27c3c17fd6b1d2abc5a283635bc19ad7f55e8a89f82e360ef581c679e5287a4d5036a86aea5a4e9d879b5c68855b5e17613ecaeee7020b4eb3cc8e8ff41da8c9f2993329766a57959a303ce4f2977f6f5bc88dbb06a7dd496c9b158dba41b9fc1489d0dbccdac2f1e6f4ae8b7b8803cf0049f5d7d0db3ba6fefd629af420d08ce1c40b38ca61fb373f1428b991708c0518ed57d2387ab93e9b9832139969a62b12223c67f1fa7b2b125573c1590cd2606facda8a2529aaaa31eeb86f17fafd19341d6df0c3c43cfdf82301363a406f4fac97aa09183c86798972e72146beed63c0109538826a2c0e15e34b75eae9d4516b17d4f4decf8c18716eb5f9fea959b1dba279bce472d4c904c205d97c3b0b745b960997faa9459e50506a4524b23b72efebf0ffc2633e08aa9d3c12922eb549242050e5156e548f5bbd86359b2a946e0a187482722e513b74b8bd331bb97321f840ef95782788d814d4419876722feefb2579c81ef8077fd8ad4df0ca0ff50e49f05db6f5532065c37e1bdd4ed5d792c2deafe7f80ad5cdb6cecade3e60447635cc7becf43c2d4d9305a50bc41ee69c98000ed5a5032da849127bc3fba97f62a48018a20fae81bc07acc1f58424893b6e199a77622903d997924d10fe294d752aacdcc564fcb1b1a05bf9a3bcac366f872d9d3638b4c81f72d40fdeb90f99f3c2bee25219721847039bc65afb241f674a97516c3d23df9a73e3e399e10061f13479916013083fad13c52a2bfcf959f77b375e6fffa222bac0d2a3e854a529f1b9f0f163451df289c21d185d0af7783200724356b39e05529bc9b3452d85bd0593a2c7e5943870b3fa16c707a111ad71aa2e1a344dd6244ea4712dec463733c5a4a49bb0e84c5c8f29a22530f8c5c3eaa40a1445f226b592da3e2f949ce5be3581a272b7024d162312bfeb7b99b43cfbf67953f7ccce1abe9ea37f2a996a3d8d47708033dba9ad36d7e7e0f847153ed7be1ab24925f89227aeef0f5c7108ec702b94de37cc9a33df561909e027f5086a7afa598d74a04a698be513ef1e28b0e9260930aa40ca2352874e236654ad88dbee32251703fe9b7dcbb6837db64b3c38ffcd7a379c1fa8eaa26c0b4cb814476f15891ea2f87725509e3b4442ed9fe04444b6f6f48d34018a266006c619552a6bf78ae563be0c344668956aaee331d8004af10592c61c3f50c9fd78ce554707f078341c459fb56285ac07152bb4565e423c866d318b7108d41ab471a5d50d9ba65a81a53887e0f1e479d53faa6e8da9fb5d7df1d5645716db7abbfe294622870d8f90e52aa216f9029a82a1261132835afe679a0fdf080e1cee417dab10086ecbfb949c83bdb8b4289227739f0da869db6dae80f93012b8e36ed2b4e8285830baf45a06e5bd8c77f699e279fb274370838c2bf92b8f8145dbdab2bbd1b376b66f2b84a949664fe5dc75ee5fe60a2ee7330054a4dab1a83cad84baa3a19349329f126f36e10adc8935e7069ba145cfab3c073d3540c2e2230529dacb6e4fecdbdff74dc4de188573d42aef38a3fbbe6809e96e1d3812aa9ead7c71d56ff0780948beb1f1b5c7fbe7770abe64345b3781cb8cc8c6a5a65fb69728daa7a29af1e30c38afe10b6f9bc39bc686403d1bbdbe2ab633683f49dfad66e42252ad01f6393cb624ea867e7794bac38786e02bf71e76d651404394c63e41fe9f17dcbadeaa729677b38f203f7412ab2c0960b57ab622e419deae57fa8122215e69d8215a24bdc4db0f12d1514d3519a6a5adf7116f794735c919e3434f49ebb9e9a1686b11aa08c6cedf3f418b900988fc7cf96f38ccce2490ba64a2fd18b4fa9fa463e45f729e37a5c7632e7d3926925476b93d03d62f305605f9a3971715572e5dc63b66230a58cf13a0d99ccacab4e58ea65a815f771691048367ea38b53bc788b8b1074a049d37dcb56a762113af7c2d6f823012e3dc8faac43f970f2fbb286446f5f9d2b12022a463f28f1b55a4fba572287ea772b936311d7736ada345606afe3cfa0988a9d7e7680baff25cb9a8a2215bdbad757b2f0dd331607cdadbec79229fc83b762f7b7a14fbc245fee7dd4e3ae524f9da22b7b3b66b71b8863e48e057afa7aaebef3d1a1ef50e36c115493695fcaa727c13e42366f53830927c505775144bd8669cf06cc4771d49d593cf2088f0b28958c3771f92b7a7c8659e1631be898a798af28399870ac74e227686ae431a14ae4a229177a0622ff3d5f5e502c3bd88a93f087294c0d7f5d347d1be393c3de668a60b27859d71b5fb7b9349b50e2c4384b731ace3cd3bb2052c890565ce57eab06edcc4967e73b3d57fad127c128bb98d46aeec2f5d212fbfb14eae49e3a1c704546cc4324be899493b5426da4f65f599452b3ed39c95bd08882c9815c811ef0756479b505acae02d6c116ab409fef76631672cbbaae68cfaf39aa7e55af3213d1e8a914fd256d2d81557544fcda7a175ab49bf54aafbc670b8873c08103acc7dd597abfaad4283642c000e5c701d45ee349d6a5a445a7c132591114964a0d8c75dd9e4e7a8b3df54fa0523d0a0e22f2abeffec08f74c776695e3d971511fff1e697509f60e946d67cfaebc658978bb2713b17c0da56745b74f14ad5bedca73486e732c83b80f9e4552d0cff87d515a171314ab7f8bfc8435c0dbb682390be726f6c435614623fbbb1c8469ac082fdbb4be4f77336bbbe9eb7692c3b0f5ceaf33adef8e3e1efd4130dff0b6a15ac25832240f283119fb5bc803f012cbb3712a127ca1b9a2f81b1272b071fe82fa39113e3da50ed29ee13a49f7d689b5e52aa25787225f0fa6a32621b9b4b3beef42fdfc9a49fd6016d4a3c472a96b745c1240b097617b48ae4067a57112f1e8e29c841513b37ffaf6d2c80998589a815233b3fabecd0c491cc32d673d1cec21d423ad2997d00226a160ddc637bb70d5f3e55414927a12e79df36cae7e055da4f6ff8b8377263ffd47e08ae21f32a1475a66f024287f9a56393777bead5a714f02706207d5ed6a269231490b4f1b19035b904a9f981dc9e556cb41731be7390c8ebfc8681bca0abdf51d65c8b155d317fe1d8f43aca9c92171a71731d74db1d4fa958882bf7ca564d0582d2d56dd8b5379373b4aabab4abdb5a001b3f7b443d10a45b8b315ee14a13abde8410b5daecd84fc09c56c4dc0a27ec3a643ffed8bf23000831693408ff72d03135f53ddb7ec2a5366d1e5e2811681e6e3c8f1140794e0718b298ed9f46ed561d5be7030071ce32a5a94a4aee8b63407266be3bad57f4bac2691693d9181feb7576791e80e0342388db54726691da282674ab02c5a68f8df30d26404b3e3147f12cbe0f57f7f5cbea7297cfce06ef3b0883233b73becd5565dcb549063511fe7f7d0e6aee5efe70c0b7468ece7c6df996a24147b92621735e61c7e9d59bda3ffd50414e546204cfa0aedec5434c1c8001a4eec04e42d0e9155d792ae5050f4ac75bda604cb11cf6d3fc445390e83017118adfe4b4ed3460d482f7e31e7663819019d14c6c9d23725e6b41617bff7369ba0b4e75186e079d1a755500cef7d680741167a15441b998186ece1bd2aee4dfe9410b31c5d2e80e3204a84d811966c8886f329453656edb70cd36c0f924fa798990c51e8c681d750bd894bddf80352d7bb895e85b66c645694580a56ee978a6437b929c08155fdd7ae167d84d2daa01485211ad021376ef865421085e82270b7a5445529f86049bf017708186797a8470811d06789ba5fd9966493f7ba18bd42e79492eddfc4c63ddc72f1ca32543e33fb0e6910699d99d6991103efc4f0ff8b6663415093a0bd594ad179b574be4a33bc84b5ee6f66fd54733660729e548b00984496d7c24e16d8679644c877681a0a54b4b69d5fd72f819edba049780ef7a2b2e368c81d95a509b89a351f1518b2e561bb7c1df589952bf4faeb7b784db9afdae030f70ae1959d364b288e19fc8028d64ed0e4a7e61449d5e1a0ae926ee0e166f15ec59d3817d855f568b0f8ca45ebb1000b4f1364060ccde4bb6693da0dcf233264bfa4c9756f73e4cd1beafee1a89557f30eaf92febade1ce44b2f2878d9b463b4a2fde8bddf57cd7d4739d8d8d37b775b13e46d4477cc683a3acf30a8c83e5a6e997d467a7551df2decfb375a7698d6ae3d13470a108a895d7192388c41d5be45bcb9fdddc71b195303c74c0f0e5a31e2cb489503ac65494631a94f33fe0d1055f43ab06836d55afc0593480eba74814bd0fa8333e0fcaa3bcd4472c55464ba6cf136ff46a79d2187937a6f7b6e367b292480d81aa6febd845ce656bbf2f40b80f9c59b7115c89d83075738f858ee301536a245ec3bc94a62af287e321140663e25aa671d3354b81f67dd0ab840069404c908e2283c9a9b1e9594fc9c02de87f5ec8af9e5af8e872dcd37f8089fbcd168dab16e901d01abdce2b3d1a969745c46bc83ffd6ad4fe88b8420dbd708ac57c601a20d0008cfe2d45bb91f909e8d038382dff33da47313ba5fb628064d4a12d06e944043549c950db6213d0591bc69e3c28570f3e23ef273c65ceb095f4a73786af3679e0b7a4d0dc26f170c8ffc19cfc1b529137253cbe94a79f4189ff03198aa73034633c9c336444c528af53e4ea19840f45b622ee808ae9c027d3fa2372be2f4feb73347a30ab49d7dad56ac63fa3059a7ea4bffba30ea1a862b318aec1d54416776189bb114c6b1a71a118b304c21d8442d1740194b1778c0ae04b964e97e5dad877f0dee38d8a5a965c6e39c13d23a3215cfba36f34f4ae154cdd49711ba19c7963c562cc384b7c42ecdab814d66f9b90fcce048585afc6cdbe007501f19841daa3bcbfe77de83b308c4f875b667b4670b2e82ac908e7689c93b92e900de9745a4f30fae2fd8a1a4621bdcaf2aee794984619c09308fcc2636d3859d3352a8fa2ccda9d81404c32f70b94b0d7bf5f5484cc1f367f429f068fb0ce7565e17fb06a9f651978055d9f35d6ab5e4b15f1379aad5fae8bcc935d11a375718bfbd8e1afb741c420efb8e3a5caf69cc74e09b7e64c5f4d49580b34e66b623e2a348ab677f6646c97df6fbbdd64a450184e07c6d6d7073d27bf0a4520700e5ef539c4407ebae06ecb9c21c61a02c366ff5afc479e3d37c426d796853e7bf572d18977c1850897816ed3ed8a34619686961ccc3f0d40d338d4cc7436c3bc70547099a1d8c7208dfe7e12ae725becda0e7f03ea79e18b2ed1bfa08a14eda013f07e64db84e9dfd9df1028cb0c2280a6697edd79bb4a819aa9e6b5f07bf6eb5e3cae91a40338965112f75fbc3e7a9599de1fee4851c49aa057ccde7196d812d9834ad41e08b900cb170098b7c1b071f90080c644791b6df163d2ae1aa71fc69f2e00935ef22dacca759b667c87c15ab583a39c3706649a8c76efb473b1d98decf3e44eef6b893d12815b39574bded204c73af2fbb44f5a37d725c3c4581c7669d1221b2677d4571871db324840e0bead09962249d15f23c35607d3b6ad1985112b4fc7ab8ccce2eb5b0dd0f119c3b605674ce9fbe0263d970687a020ee9971219db6b81b656f5910e4043958b7bba3eab7e54ab7c356c5188edb4db968f18bc800f0e7270bce1cdcceaf03839fb1d49e581f6dab50c54fd16785c32566c934a2f257b6fe0189a5abd52fa1a475f5c2fed030ed20b47cc4d8f8b59a9411832e77dc8bfd45e1a117af2ba3e7e5457d4d280a339068c7ebb09c23f74074cbfee7cbfd745e27d380f7ffb8102628c440cc7531fea4aa11eb0f87348cdea6d756c855472cd7c840179ca8abfd456b9931e6e549ec5df72a97d21f242f03bca7dd064a80cf9c83d5889ac19b59aaad892c5de7ec139d981a26ba16122fa6413d63a301010160eedfe7909df2e4e974ac538991a75d90a9fd8f800e9c0dd64e96d3d0222336ae60da368ca40ab1a033a1abb6797ad70a2fd4b7237a28f89ce31f29704991d084fa886f876ea5c2930bcde729ac66b4db0219861fb82a5618f3af920353ed1608ff2ba39ecf0fef1235d42bd3f4566849b569055e76520704fa6bf534aa89e4a5af30662783963543f4db17dd14d950103b719e200e04294cdfc93c0b25c2bac8cf27a1ce9fa4247bfe28df2ac675a11e3efd216846fbe7fbd23efe13ba85edd8e2a90ac300449d4fe346d80710c7ae398a43ada2af153ad7ba4d71db48a918a9a4497509fdfec123395765302a842f04d9eb3ba5f0ee91b6c75381dd313a22f7ec9c1a52492923cbe6835b0a4a6e495bf70836d7e5a384a86bc493de5affe091d9aca65c90a95d7fe940637fc64bfc73abeca0df0f7a0947bcbad1bbd0b59577d44d54b9dd94fbb523f2c953be9d67465dd4a3825a73480b75c4862d74010267835283a298332235d7e41d5d689c115e2eb25a6969dcb04266a997f2bb1708c9432d81e05d712baeed92e3a3a3b9256f19d9d6241b8f30af99502257a95a8612b02f08afc1ca30bbfca06155b697971b674108e809d88b4e81a2293da7f1abe5f08eaade8eec2ad5683e8daf9b7261434c2294f2a679b3787ea4c9479e28767ddde7e49b2682932571eb1fc11200cc5dac75b8979c4a367b133cc476c6d6a534915e6fdfff05c4a7816fc80cc351ea638a3ab82f644f6e4b35d7860d6276ea4558ce4267445d60a886ecc4b2edb57b7ade4cc0047503bd8f13281398b3d5e4e2709b2d6356c5ea6ef76e516e8e9d095f363762cdfc4ff779c6d9c7cbea9241c1b5c661ac92615842b61349907120f9942ccd464bb3d112ee246a2f317563891d25c428783bfc2bf9e8cb2fa74d3d91058a63842e0488389ce6afa9acf37d688c42817ab446473737358978dca609cf02b637d717f816316750f92f9f20980628e040a5fcdaed9da5a09275441fd07ef16653afe234a6bb9b264cfe25d1e6073d0791e1177396486b1c0eb2115d2c0fe2b376d4be046c2ac660f65ec3a97db9945ffef4f7e16c2323a6bd5833619f12f0feb9c8e39ca97e0845bd24a3df958ccaf83309b58cb3d61c4245808718562abeefdafdc4ed61b5e1cf2f8a1212cf8625b5c8848dbb81147de16161bb59b82ed9386e0098dd381867844cb02bf87d049f7415e83c311bb77632c254cbb6464d5c4ece8ce099c8808143a7354455194563f9dbd434e80f7acc61fecca37b7efb9acd599e49a3da14e369ce650810343c1a6128a14270fad685cee7ac350b60fdfc57c0ef980d0c72b9c932152f257699577cd54e1af86db870905d835cbdea768fff3ab3d6960cdccdeaa5d413087523765c672a875efe864c6f68300910f9f997bb028ac1eb3a9eb910f625e406aa6e769be84656cd152ebd21f0896543bc7506a135fd91d83caa76975fe704c6cceb2ade991572bc0bee225d0807479000915fe4ea01ab3c5df3faaba3dafd351a94b388b6c3ad8056cbd7b316ba38f3f8be94c10db05258428de6eff07cc369e3a9e41f3fc4b09d9acdaf99986d730cfe9684326480d49ea02d3a5daf419351c4f4578f84cef24c077c127714e2fbf065652c79b0dde1b18720f2fb7e3b44946eb5529c424980596c2d259a2105e699dc97ae779de013fba64475b7eeb8349050fd453b1099744c956d46a9f5e968fd065f9eb8c5c57f1fdfe8f1f238084ba8e77c3061c95c81bb2f8121ed15edf3ed3c662be5e6d3ca5c82ae0a9926125dc937fc212e553ea6d01a2f18212ec1886c37eb40e5197b54b9d261b950bc4fdf917d145ed7ae7a0f8f4c5e9b05eb31c1636171671b79b9828d9880c356f6b4ab13bbca2c0c4d69e3a1f40ce26ce25ba466f88226f0ead16be9c21e3e5160b12cef3ed2d8d23ab23ac3f67929a6276a9a873c53f48589fb5289eb35341a268e63e204edb79f1e247c261d7ab89a38cff5f6caf918bb43666ddd53b4ad7f564071807e01c1cd518aeaa2abf114584018382ae608ddb0f582519e6e4ada7e13739f3001a9a2a8e8ef8e1b6ec9e757f7d97c721d9bc47debd1063e98635f2f873d8eae9e526dbb49dbaf9ac391080545e9eb9f3ded9b9c78f94c727bd039531cd16e84e28e0386ed0a29c056573b2169af7cfad3de53401544cc75e2e9e803cd2eea43da53f0a0dff2471b28c76c842c4d39e9d9c912aae7d8c5f8f995c98591f690904e16b298310f5c05aa85a2ff310385c5cfa7079aa25993ad9d8a95d7c38ed678be4909f368d91223b521e425c4d1645e80d770c1056017eeac70cb3fe47a48d888e0d6c683e988ad3f7e0f1823b64ea4e8e851b5d7c25d15483c4b1a16fd40b9984217769fa06d0b0165e72e472e3af0197ab1f3351eba8c0214109ac8e6d121405e1e1773eaad77a845af4d7a7edf068160f9b05ff5a386eda1e11c09a7fd645c0aa2516cc6f5670fca3c184aed0fe168f2c5368aa7028014b58ce1685159cf2dca170b8615f6f439a74fd6b7f24de9f3f5d0ddbdf8428178d27c3feb1c61f8ed4b3e0ec56cc2826078f47218cf9cf820f46df260f89db920b03a5bee7b32249b71de2eca568d941b0287fb768ca37f0214fcdf79e2cf07757d4c5c7296610ddbc480bcacbf5dcce15763502f81388f11a197d56c146a3da18229f7c2c4fbb6ae5ddc57c27d73ba231a447ff35926ed660beb499564464cf0bab66190ef2690bf54d0dc7f3db2b3d98e1c089993167b3b7a4c93467573f1e90c52a11fb191f162d1dc12147ce46ef0b254641dac8b5dfbc99867be34e212630ccffe045c7fc1136b5be84af5a3cd4ebc0263d1b3574c30c15c6538ea7bb090b9627ee122672f67e8063ace6bd1a020b130985b1cf4db9f91e61bea0d532fe967f1f41c111d25550bafd4da300ccbcc6f79dda6d96ccd183444f1fd11ab2cee6b0b3db8b2de73bb88b2b23082b4739079a7686b044526186da5a405d10edc0bb7e3636d295c3c4ba7f5855cc3bd34ed2d08ff50e685e7137a6fc4dad978ce6309dd635b25ab72bcc27b3eeaf8bdf7d9771b5176e3c4bc294981f9fc165bea43359d548b1a3a6af9bfe2098fab842753f23f83a2bb615f9fdf6eb7e1b3cd524061aa041190745873b11b4af962a27af9b1441c6e8451044688c758d9259d82e6ec1a3fe956507fd49c03d6f4c9158e2ef6affab3c4f4480b7d3a0bd633ee4fc8eb2ceb4c4c8f62ea5bd01eaee1eb9670841452a5b63729548ee3b15e9773659b6ee220759db69bee667b11c5c09e84926d948dbaefb690e37151f8f92448007f9a8978f23383ce0f763faa43f4c742262c1183e4c8e163d436124196cfab7429339832d2da538e9490d8b18dd33cd4df40dfdbb91f00c078b494a0a09a2c666d15b4458426ab8b0cd94a8a37c7461bd4fb0c0c0720fdf4081a89b8937a77ff366ba37d1d99da46668c9d81f737d71b67122cae3d6b0469f6da379f51aacb2bbf8b530005cd9f6d50de77f9bfb9b73877612bd1cb9a182087075b7edd2783aa54541658a97ba1228eb17e3150c0a9199b76c71d21cd069bb33717eb11b608b45bca0351bdb8b0242e266dacea3b108c8d4c7595b859e3642c1e9c06aa1cc4ebf480fd71c01b3c5a52c30e3e76815630702fa1a8cdc56f3776a38710871fc8114ee0a44351fa88c0ac3bc66e66a011c1d35e2486acc1fa58a7a3a03d2dcf7f1c2659135d45ca8c17c69d7461e30ff2dc823ad5a27af6177f4c9dd3bb9341c09b543e224a4dbd574ee845959a4d575cae935c0683921e64c8798054b7507fa5cfebf65b7298e28a4af2328057cc176096871eb246f35e1ca8be6feb440732c4a9b2a8d466691533a3c95b15754b9b79e405d8362fe76a26bc33b97db6b91be0328c3ee6d1702ded3ef48c659d3c56f9e5d5aaa3f5039636884ec89006e3a3b955719990468e926901eb632637921fbb4184f08d317cc97b2860e1ca90d151eb280d7735222771e109eb4db9aabded4b4e835920f9c08d608596c7516b328e623ba7d806359fadbed695d8f0188e5ff13fcf19ba4909a98be148a445a66b09fa0ddad5da5f997ebe01fb45ac7b19fa692e613d55e536e5a5657e73ee88db23ba023bed0146842db9cf4770f7a8075e3906ec0cee5a514737f7ac67c237f9eec57f94a78f92d122823d9730a4864a36776951c3882");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("HASH-SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSLHDSARandomPrehashSigSHA2WithContext()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("HASH-SLH-DSA", "BC");

        sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")));

        sig.setParameter(new ContextParameterSpec(Strings.toByteArray("Hello, world!")));

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();
        byte[] expected = Hex.decode("1d01c0dd5a0ef67061d9cbd6d309281505774a7ae4425a07a60afa386a36ffdfbaabacacb2f2182e9cbe18ff58cf15231280305e78db23fe04861c9ffcee2b78318fa96d2708bf43e4192e3494f9468e350ddccb4efb0046bf2b2e861802f74e883bf045afb0cdca4b7bcb79161c287d7c33303bdef87cd0b1896ae3c512435f96ea3e48706d434db1b78efe07f465fffb3210c3baa4e19ee2e67b42a79f9660c0b1211285685bebeb3cfa5ba740b9f1089fddec19c50d318b5b98f66dda2d75a59f45c9382adeae63a65efc52e59c5d989dc6c9e9b3d47be6e12ad9123b7709142d46a4023995427d9692c302f3a4e9a1f4a68d2bc341154407bc85593f85ca36a2f2ffd2c6159f90865e9b1aa62eccb503821f93b097770d3942a89633fd5064ca74cf6b00a6c9db0d4d456b6520ca83153a101d0bba9361a73666ee4150ca07165313102fca6f7f529050c6a1c908e3022d40530990fa0aa13c70ed800139b142dcc56f333e40f1bb6ad1a4406530f53cf1ccbb99f90e1aa7fc2c3300dc53570ea4dc44f4ecfde2d95c0c280c03d45de13df444784b5755692d184e8c5bbd8de82dfc5578fe2055863e3f4b843fb1c0b52d5b1596f0ebf677dc2324722f2dafccd6d4892007bd0dda08b206f3ae5454a67dff0b0d532031c32576540c772f78640dcbdb51a421cf90ff1e9e28d80efd76943c559805b1a3adade7ff3b9b339b50d5c797da7814beac265b13a51849a82b8ba4c6034c29604f2d9c269d1dfdda9bef02e26d232d90493ab50207dcac81deb2fdaf8a0f378c8aef9945a8fb24b4bcd6049f78e3cf93d9cbc69ec731a8a7cdbf0a38f0aa88d62b18d7662419dc496ec53b44e7be7a92e47958c2280bd68f2abcc313d09cefb03a1ca6951052cb03f6b3dfbe10ecb0ecb3018aaf5fc7eef22b2b4ea2bb34697227ad9446e0a1191221edb2bc02ea2ea320ddc4060772d3ea9053610e3db6377d697b7b6033a61ab5980915aa976eadbc2c2a12860a8ee00a736ee28be98f0ce9ed9816511004020ed3ef0df82b2669bb06330fb14b08440696a876c28e3a285824eea7ec1a770da95c74ec30849b487070b3a603c398718edeb0a478537b2162b7799db93eafce5a7766b75d203f4e7b8a6ea589c12ae119d72682213541497d4cb45f7d3bbd4ad1dfaf1da56bb0ae5dbc36ff40eacc52c7db2d202f48cb5bd27f1bcf054503790482bcf6dc56bae235eb868f8684eb4afb3ab9c6a3582660403a3cd2f208ace5cd5cef297168a379ef7ca634361f212d6e962644b369e3b126e630537446c10967befc4951f076a343986b32ccd2462131e40d6d3660ea4f4199547c1158a31cfebcc6aa070dcd3350159379cd52abc4a492ddf3f006cc7d9f2d29bc1c45175eadd402a5b7d1644cc985e5ac908274be8ae8953495359f57768fbbcce457cf3fb9e6e80a60d9ff6f44b7b3fff1be793efb18d8f6c80e87234904402d1c30406eb8da51562e69d907a820c424a456c6466d81c8792a332db4a5f9b34d35c7017ca4cbb01d434c4db464c6395e170d12acd5a0783100623d0491aa2f7b78ed093bba39ab399dc89047ca09defc1ffb6188b48122633cf32c844d883bca0eb144b364906e6f4693285077ac43fefd8b2939b97d449906a8e59dd23d464084e539afb706db7d6e7b5f13b46d0bca9b0f896afb9eafddab2542cda2f98e9918b8db6bc93dadaa756a77f4273b8fe0c8777249ef345ed725fd4b59e4d12c2e0fcf689697055b4ac2f82863d8ecbdb4809e49ad5a10942c6b6f247433cb5e8a1899b793681773d403a1d21418efd09d31f04986396313b21c7f96b3b42dc7727a0f92f7c75befa4a132b26939e2ae91c68fcb5af5352d99482115fb5b1fad8a3afa8069f55bc6cf4e14aff423aa78b62d541cb68a1ca58822a6b0cce82de0f5a8710f540892849761b743a0b7fc271c488922dc256103076a09f26fbc00ca1b373eb5847dbeeaff499962c06d30c717f9a2e6584ef441c6501f81d9cb4be8fde9a0105b75cd7cf8c6adc34290b0b21007e27ec413e4facc3eb584ec60d152df0269be3e0f1156a3290490ad68a1043e73be01bf656b7515b3664c59423accab60bb856167a95a65820729e58c9479060f3c14e1b73f222f777097c9b065efaa962f6577e460570e3b2d29e68617986c2847671f0f6482021cd57f867a68fa8f2569f7e9033a292a896bdce5ac90360319bf69ee4d5ce9a6afc743b891516151654f29bb4775a0d400b469a7520d1bdbd084ff7acc6e5262fd3e45fdeffeb1248d8d094a5a5dfceb1d84432b5faeb967db0249d815308a40815db664920e2ebbfc06f6c3d7bae224bf787995730fabd38462b4246e4f6a68403566134c5dad0ea22feb8c34b0b8b8f1afcf45027e1f62a0fd225900f850b965299ced25938c2cdc853611c41b1612ad867cdb3dd2658276ba6aaf400871803d7a57241bef9317f000397d6cbf802b649dc4c82a716414ce8ba9a8788869c64aeb6c2cefbe1ff304c64596480c05be845ca01a07435f42907f9bb7739f86d10aec0041fd79f86353ee81e9f30c0bf640d32138f275bce8f9a49b77dd12fd6600155b8380684c84185df05db2ff282777eb5b29e6ec11ec3b244aba3f09f686637ec8971c6c914e4b8d7a5cad7a75a2db33cf5233db97e1b452880e938b09e6c682a1a449cac9cd3b9412eeca325c2cb23d8440bd7e5acd613d1079d6961d343df9216617670267ee3a78a09b0a84b18e5388df5e67b0eeb608e5f009176d043de9dadade473520fb89929de2da34e8165dea98c8bb9819d818150eaf6e8386ad86b22f8ccbdc6cf4d903d1b6ca7cd4eeef63bdb603859d5ce9fcb2df8a8f8e58e731ebdb8d6eb518585b1a3bef5fc7d980bfc30053a9ae0512914a3a90f8e16d8b14edcec070be1b8975e83f3e7cbaefd7d18de48cf0e51a7c480df1a3cc6a3408de93b9724a125dabba5dd91db6b5bc3a0ab638d509259d8dfefda122e37beb67f0073b8ad701e47e62bfa45c0ec7300e7833c1b965c09eda4eea6c5634bbf81d1e3801da856d6acf4387da4a22c4693ca6301a4f4809959c6b8837931b8f733ab8dd136c4c55903e59f64b9680d73ac4fad0121b71a0b22bcde2ae741404096612871103ec0cfaecf1a1e788f64d53f85875e519542b390b842fcd3b6487070b0b4e5092ee44794e77fee577834ac835ed223e80c969051f7c6b44bd99da138b4f9a7012fe3c0b0089395c8b50b1f6bbe0a0481408025428594c31d64a4262c90d49ecb4787585e9c1e386f1ff5f091720763b806614d100335888528617beb6035a800b91b2330e86268db91a6606359115cf4a61fb37dbb7fda644d8d88848a29d38d8cf984db8386b9f667dd96b6ff7727b4624368f8062105aa5da68e1ad467691cf8bd9aa7d4c83a63f7861637057c7a033a1c6e8315164b0deb9404b2db4b14c0d125d4199fa24b6fe6230b12b7cfbfb516f4f3de7a22dae501013b6cafeed0f0c58b76c87e7f10393a6513a2c298c901cf8f225a42362b611d7aaa55c1bef3cd9779ba400c4fef504bcd8b0b63304c1a8218b91c16f87d123dc691ef3cac349cb2c3d0b0207412d3192f7ebffdb5b3f2a0b9fd4c7315ac131b75b7dcee3a7d6a2bfa92dad5247edcb8e59e34206813821cc7020b74e5952382fe6d501169f0f5f4c0ee1518da0e0106bdee891f4c4f1873f4ff487750c0ba09b826acd49f3a0bb52f06511f5c718f8ccbf15a7eefc1984062da04d049bb70baf1ca720144d0803b515e60369a8e8b528ac1dce9e2063671b7b59e9eac4dd6b567bc76aeb04f48f8c881380408c22e89388a8397a4b91fae7adccb6d5948f87e1f307caa593ea712ec081b91da3d59171030e611bab9999c52c6fd9b61124124566c1262603551bfaad998390e7dd304f558c676af0be96f3be138fc3e5fd3afe594e848515454002c6c3a2cece6955e940923e21cade0a6d6e788a88c34468550ec95bd2fccc02f436994bec52a4c44aed40f50c28c47de270175c2ddb4c6757a33a35b917f79407f738ec78e709f0ce0f9b0606b41799489bd6e3a6d51449cee4c9f2188cf08197d18136178f2d83937afe44099531041859e778b363e2818ed2f18ab87c2c8ee47553703eb3fe3ed4524eb0921830b6e204c6c39dcd09b90387cfeecbc193b76ef9d195c8cfda3fbf84b55a5a3ded745f271d912de95a2ead29333f4a7b8b9bfa2f945fcee4374b0f1fdcd92f3b592c3212a936f754e5b4bc16adb87c409169da316543e731cc22b5cf5f6d087e605a07707b2b46d72373a467a54b3178e13a3339779551f4c5661cb3a8f3f439654192540232f47d0cc61245551031e52b51be89d8524338d7097508d9de624d27d6cf15efee3675994e5f218eed994fc09d4a58245d16499abc5e4e6e609bde2970f1501ef0ec82665c460c8667cb51b240fe8620ce5242b8a85d83aab762b57a528bbe3d0c8c8a2b0e59af61cfc1e3341a1e1710ecdf859772b357b9fd5c7ca06314b149d096c9132225837981d300f097d7d6924b814211ea763240d127d31657675c6c117bc71458b04230a40aab2b31c9eb7c480c64838721c2d666913ddccc3fa12a734a9e05649da1ffc8ade660efebf600c71a985e9a7bec006052857ed7af8b7f618f7bcadde425aeebd21d78ee43d6b233d9df8f40fcc49dcdc844aab922ea97bcc8db23009fb822c5145176e1f0d71c81e99e3441eb9d8554327b20580559b47a1dd1a59b037bfdf04153c46ba0ac5ea5e741444797cd947b2061d88e6e763a84db4dc25987a07798c121d2505560c4af1f0883fd44be621f329164874eda8606d5cde7ec51a8b6163107db9e05ffa32107260ac725311867deb1e62cb1abdaced0cb7d4f5f2748aa1e493cac4df6b7b0226fc0d785f5b3947a03fdaf85dd316286906b3a1efce033d086b280a2d1c71e8f9ff984f682a393828547e30dcace48ebdd9d3957a2adc40d0390d502bf7b9e4a6fc6a72c3601bddc4760c9644519647e1532d0dff21b5317718ec7d960ed9c69d0439c0d975262d3d7bc997a072c3a98be1d5963b0ff1d199a6f2b8585163f7c0522a967b79f68a109bb44ff6e67929d094583b1d81226412f8f67a1167a368173a87cced1dd4934b1fe4e5f0c4bfaa94d54d906387383d9f449ada9dac1154d5d4e248158dccae0c36936b2e0d3b6f384abe458141168b49d815ef6cdf1aca765bbdd4da25bee98cfcce7b732fc7be83919df86ba2330ebb426b847d25df44415798a7a9fc24324aa88a6108efbb63eeedacb267636b6f9152f19f8b05656514f4ce88a63e695e017bbaa4121a94ce0583cb6fcdddf1c8dca95099ab6d348a72f5c0a96006d8e12d343527a5001cd7800bc35d8efba3e8574a723caa643ef20dcc9b90e8b25ea145f6d744f822070490acddf4ce87e58e9bd79517643c3db12d1b2e93e26ab13906ba281dbb47f40fa395cee6c52712a020efed17e3cb32d050387b8403a953668ecbda4bc654a417f867040dce3dac2a526a1777736b5e9ecb75968287685449d0c5ee68cbe31751c203215e27bc8459bc63409d7af8de043f861c65387b3b46c22abcebaedbaa293634abaf0096adea37040a8122d7ecdd156307590e7a14bba5ec8215ba9e303a12bf6d2cf175013942f613158cc8e0fead29be85f363f0c393abe6dd35d9c028e331194fc964432fa3b826dcb427960be5a5b7591631dd3f5c9866d3deb2cb4c8267da91455bc0f19ca29badaf770460108030328fe7909363d442540963bca554e5aec5f663778471ac4e2350fd33f78725bfea40b2cff9deed4ffb72cb0fb416195eeb8e0e872397b709cea18294723ce82e56f390cd2ada2d3bdd7c554e22810aaed94ef65dcf86cc7b46406e371f9af03699d7a75e45a19bc08df5058c4077360cda247efb9a010ecd5c3fa947f3dd1231e3cd25044f95a8549443cf356ce9f22783e78ebb1e07f96ab5ddab325fe9e5b93f4e2b91de912326b2e138258ba06392de3f313f31786a281943b35732d7d286f209e192bc04ac437a0e51e7d2d75caadfb36290e7bd375449f06f32a63d3513fd6cda9b487e6915727e9a4c0724903b5d83c7c02b4a8cf1af5747edb72d1c5bd08891335a8e8738bc0d1db0316aad1e8c5dfe43f2f8376dd44ca902323d02b90944ec0e3d7533d30dd3dd8cd921819e41d429123e32422449758295bbcfcc89574753bf2592ff611cab5664e52d95cc0baff388f9ac2a96a020cd90bd83f1ccf6de4b476fc03185e85dbe5a673e5eb12af25f2d366502ab876ebdc0b7f5e10996d1042e4914adad2c510d900e9dbb6e14893f061d6934f6a1fd6a022571ed4d672831ab1c68c84d3997148c064e382172fba25c316b7965636a79e914e9ee1c312de6e6ac950791e2c454774d1da08ba76cb69884cc9f31e19096f3205265e569471b8ffa3d814bc8fa4a8c72796525f442560f631fdbd2ec2e86b15529f23a7e38db0513c042f98cf5582115d7c750721c480d0a8e8902db069a99b011808fb4cc80a8ccfa52097676a5629d0f19e8d38bab66ac8133f95c5f19e11c07cc042197104373363613b8c34aa1849fb823f668e697c1d9d59bc1c70edcbae8c4c4d4fe3f3287893079cc6eea1a82f42b36b8334439fde048b6bb7ae4558b4757e4c4b4f9a45c0ad76c6555a61445a3d5511cd0c5b5e5769d0242352946d44e0747f8fca074967545b1787572bab95c4383c4c2e4ac42b680add1e73f49f4151d23519cf1ca3d7825deedcfd007eea19e8c8df4a71ac483be225d532772cc57d13e1da38dd4b3824b2227fd2a55d7ebe7edaf8216023661fc6b98a7100a4cbb3ca1e281720bf2f6c43b967f145a0315963e93ef128495ef30bbc6ca66d2cd93daf80998228e101d1714ed99eefd63f4b34b178166b00411a1b0de8d0a6682274825523f4688cd844542e801d503c27b094b3cea18b619e2299c83a1289e6856c7fa74aa5b4b647c738ce7dfb732bc394974429e6b22865afad4dd387948346952f27847247e750b3979414414f37107b2750d491f699b501b4b894684ca8ed9f5d8d7b54ed4697ed0e47621c803702c5c73abf9372f10d09108907b2d8f7452e8e6c8cdec7c9b688a4af60a409b25e6df5cd2ba0529eaa10568c74e4139814512acfee8cd93f1fdf650485c749a3f6df4d8c206eb86addcd35b9a39347c1364e0ea53a7480ff6e0ceb6e3580af99e1aa609f6ba37b2055272861fd9daa8daa60c51621bd8f2417d92d10f531a12de5e427b326705f6cc19d705120342a0978712fdecc6bf5e4694011a56ce16c6fa6ac3527df355bab2f64945a6d13accccc7b0db48bf549dc0730670efe427c556ce5d31c035d0aaf21507c73ae8abe22483e54c2235ce31e1a37f7165d55a2e99f07961dfbb3ed26032f7cacab1b5253ca08c6193c0e528e4ad91c325da5e0decd478c1452d935065153aecbc09ea7a59f68946cefd4c79312bc8d1d5eceea7b2c334bbe12632b14bdaba930373815acfbd1faa764995463ce0e3ac1848b0f084db540c0bc52ee0fa9fe55471b9fdad37cc49a71298411dc97ee08651164daee3dd68fb22c308b29cc1cbc6aca225d4478feb488eebb4e845c06eec07c4ad69e7b9058abd6eaa749c4d0dda5d488a712df26b8ecb7cfc9928922171619c3509a84c0909c015ca7921f37bf04e6d5d567773226cfa7487edcd57fdf35981ffac2e5c0ca19c0d93e86e0695b70362121725babbda95724b78e1a17f45b58c9d3490815c3e72e64709a6a767820283bf00cbb5dbc322d7bb1252a7ccc1f7a074c374d13a8fe0a790aca974c880778733e83dabfa1a8e790922af264ce19b27861f66c6c860963d08d54903d7e68c5a558c060b00d431693f8619cada6c028356227395dc20fbf4b7478a338fbd1bdc33e1ab320eb4c3d5cd85650634b4147e50f7e3ab89b68485e9806c21408199445a6237bb29b2f9a939be2560605b9739d95c7e1c7044f1ecdbace3a95cc3fa1dfc8ac190eb5ba84afc71236f5f6be6c24d7d5d57ff8549285350d2439d61ffff4e691d7d06a6b040a9838caa0492c1321e14ba41e4bc57a94e78ea16dc6d3ec84d1aa9cffdd00cc9cd4479b77dd521405c08730437fbb6dc15c358dffa5230eccd27fb7da35b074ac7ee103fe4aa8ef80638bfe3b5575e4d79174d8a9074d056ac0f1e9cdf22f96b5db9f722ecb35a6ee313d934cbcf0ae3593be91a175924ba6ed8deac57826b20fdebe170b678117186a59b8df8aa6869e8801f5516ffcb1ef301f46f9b2e87137d5596670c1a237f55cb4918a1cd983b38c673fb3d44e8d36773f7d0a8b32ad7189f838dfdf08b2ad4163b49c9d40281ad7da15608f2ada2a9472c9e17c9bbe12ceeb85cb02c0f22e72de45864374600bfc45e305ed71df9632e32274c15a091f22c5853c2056a65ec9267cc3a38c610dda91639c793a3fd7dfdbb3704e321f9c2deb0bfd2d6a101ea4988fcb3dc5894cb087c6db3c80dc8b3ed4b7a11b0f258266f01a367c1688f17780290003be6055b93577c2b78c2bf65d7b2065da6fe716482cfe701310e27eeb9a823aa096a5ebf5555aeed9d4e353d852ca2cbb14c387f279c62d4f37046f66a88381db84e4e9a23edb606ee63af8aa5c9c9f0efb30feccc1af2ffb313788f394055b6e55e16c79fe58b326590468c2c19ab11b189a870aa84fe4f789b4d7588c9736f9e8807e14801dc78da526609d71ab0c54e89721c2adb2cf77e8af063793677a7b18cd062528866c5444f06936fc1fdb8449c493534fbc6454a4ada18406856697f2ad827436c522cedda31bfa0cf8bf34830224ccc0044ed478535ef8486ef422fef0ab0bfe7d818804b5de53c1b607e004150c22d02b31969dd1710ca7a57505c2c30b1319f5df7a6b0bfbdb890bdfb4a6e4dc08857506070bf322cd91cd8a0936eec9dd9874258e5d5134eb1c2292b888732bcc9a0509804040ebf9428a8270a0c0dd660d6707beddcc742a13295c94d6568f838b40d67b3d1b61c2cefce29d6ad0ee0a6ad08606389298b9281e7c8b896dbb1ad663595173761072a1b7301c0e90b32510d646cf9113440c10d1b31d42906a4a195b552e22b2ed69609f99fc24584456b27a4e16dad6278d585346d407c71d4cdb5a817ed8bec3bc4630798254950451700fb7bf9d73cf77d4d46c7459d44db4acbc8e831bd0f237771316dd01395e0f8acf97b6064ba58db686c71455eba65daceb17ced894b30f2f7873d246ec66d46bfeb286ff2fa90ad9a7319b260f5cd90fadb2979115d948a74add1fdc378716b1531c8223546930dcda091103c2f4546d0199db7a59a92eccb77cf674883776f88f284d71aaa033ad65599b1ff2a80eea27317b22615f888c036d797fe64942b5bfaf270432f22f0ef1caeef60c83f8774b568b3643d459c2a6390bea9497dc83624343fc7b7113a3e6b225d7b17723aaa0ee8de3d4e7a3ab1b285c35b3cc845057a51bbc43c08e7f6541f56c18942896835a6689cf50db3194cd834006eab74b8bd0341a2b064a92ceb623b820e92bd60165f07a46eadbdc8d8321e964f80831d74893454daac53f80c0986c7abc538543d202c44f31767d7d5508fc97617d8c21137202e79d6f0f5f29ae7f08a4104f3bac665446aa7ee6ba97740fb2ede6a13376fb1aa71e3f5b5536b0d86ea20d9cc3fa06dbcb366faae78a53f623cb3e3354ea76388a9166aeabb7ac378ccf11a1a7e1fef69b839e521f9d0d0728444121ef3b0157ebf8a8957f37efee69f807b4e4394812c62f2ede4dcd53902270c051831429315d53d3f5a877985c8c84b0adcaf0ed124968282821a0845adcb4fd6e51a053696bd83e9430b6e1af0fbdf029ac54dec0bde49ad9f03bdfe00a22edd73a789ac28b66b20864636223c24d89acf322036db8cd8004265eb196283f117ff555b2dcea4c4debe70acb3babd05b64c1d8d2402f12f407c43b0369982d8d887405d5a51651b4e527ea4591a970d51637064c2f2b6061f562be4ffec34a30f7b5cea32f90c6c678d9460b608cf003c6d7bb7a28e33ca8d54dbc6c1a25dd213514a9547d4cf777cd5140822861e54449f13e353783ffdf33ced92e3dc6d8cbf49e79d7bb0be0ed6959570794a88859c86bcd6ffde8a9f865cfec1dfebdaceb490579338988df8e54a57e21e26374d4e737ee14dc45a437956dc99011720d3377a19619c41ed33ceaf5a6c43d02c23c9c4d33deff38b954eb7014edf7c00ad4fc4b4c5350aaf8fc4d149922940998be02c6ae19902af72d5a7b2d8be54f1def690932d61378852c333c88625a3374f0aa61916f86e0e811bcef347146a902febeb955a30b3392f6e28622f9bdbd7b46f5888694391d91a2597ab4bf4483f15446cb5e5760b03cd57a31d2bb8b295791fad15316c10b2776cc2550efcbb1613bb2e93c9326839e627a0ded17e1e278007595343b0f580cfab6e0d69362d7e369c33648db87b545676352395facd69c8efaa98705d967f6dcc8f60b8106b99c4ec25f949fa9c8744d6b9ec2a6587c057c39628a0176bba0f87812df3b4783cdab7c82272bfc364d36877d36990a6b949e1e043cb27f8f2b9ccfedcaa22f5be4310fef12d5b81a8f2ce3ae19fee5aa5161d5e56ceab8380c31c2ce410e1d31bd51e2cd709da9fa3d60e00a7da5498d5bafeb9172c58a14ada3f767a50e8fd28b5edfc5ad4def25fe9bf706de7bfd66323a58bb154193e34de639c98f90ba6082f6d71ea650b318eec21b164d9523dd39d3cf258ec106fd3b494d31f087b2367c050ae9d70a53dab8dfd94b28aeab4b8897cfe7036236e2af9c61a274b620675b20779b19fa8f1f70b47573a5372b81c4c4f97ffe8ebd84d4f359c060705bec0c7630ef0d59fd982661c335bee3d70e86b93175984830a0590fef571566eb30d19ed6e436956c35f632ed25307ca59d3601a89f882a54e2d7f0539808509cb9a937d94fe5e9aeacba5761d2670be1c1f1e71f006591623fe4a81136ed7e98133d418a0563dc242b527f13301f0d4e313b8542879283d1e57cecfdfd4102f63a75d322ed0e66abb2df46ca236b8d3e3d48f8e9e81f6fc156bc7d91d4767edb642a61335fe365b2f60fafc49cf45ce0eb117123afca9cad78413431f3f189bcbbbb76a320fa706f4a7255957787c378d41e02166aecde8d71a172e1ad36b26b67c3f6139db83c7dfed82ee42bb8c7cd12d789a982697885a2f82282e970f6217a732ec98a2578da583d119e92cefe3cae1aa81e44a1b16700e61ef0090044956a01c23e3dccf087fa2c6288f36da400b1080ffaf04f52288dcac04e4bf14f0beb1cb57b0ddc027a4ace6606490f7bc846c6458fc752df64d2327aaf780618a80b2b04c13a5fe6d18a2feaa8669a770fae5f395450bcd1d2df215ebc73faa4cefe7583f9ff11f38435fd1bb2755c0f333409136b0aaddb726704f5cb7d80343005c1f677f2eb109536055b59745dd0ccbe364e53cf6b4399f78263d906ae7bcbdc8e56066c304e37b4dc58bc38ce70c3b74cf3793c19ff59dd6d57c9c34ef6da1664e6a2064d161c7c751b094bfb07be58d14540489cb64f1a6c1874a33f02101014ad701b77050f7d03d33bf4ee341808a1d79445180ae6db3d7749798cadda7889ec1964efe28f2625a9eb1472be5b8e2c58c14fd6e3ea6ea641320c93511777d74ee69ef38f6fbc83baeebd26ed723e7341614bb5713f59380201d309b22b4a4df3ff161575524b807b6ee2a6af5419196296934de8cdeb8b59ffed9fdbc6c6a01499e24cc803aa4508f1e99751d5681215de284c0090b4f66ff964a3fd6ef44e3f3e58963af3ecaf0ce7d326b77cd58ce123d92dc84f8d2ba02be290ac29e4d3bf9ea069f5be54d79157dcc1079a048e65397384e0bc04299d7ce207271d9507d736ccf6d7528d1618f43d58ed16c2f317409be23a7b40d16d895f1cda099e65ed4c3d6e9bd6411f7b4a3987038fbad05fb8b9679a5768bccc6ac4bd77605cf5dc05fb54d23b85c87dd89d2dfb1230cf3ba8606e7a01b0d3ec2d0a49813cbcd3936cdb9e172b50cf6a76f551d277924dc2880a1cd95b9fec1d75e1fcec357df5f26028c0cdc73268f91d4bc26a4a0437bde377fc088ebc1e29c00d3fec449c6f69e20a3230dc93523d73b040958f68cf172081efcfe03761d151e99d832dfcaf0e72d4435fc83481e47bfa09f6d0e73d4b889b51781263017896c6ff4a5aced91ec3df1c9ce468ed0285446e0f38c6738c42e44f9f0557f630a5f9c3c77d1d6c21577db55c1e5d642765d4bfc569ff148aa90028968c881fa9a45d961158a1f1d6f5d549318187cf99a51510ef76a7fed9810ef852994211a12478e84440d691116a41df70e10ebe65d731222d7a730f9198633b649eba8afe467ee1a972bf605eb228850b1024f014fab34033cfee7b6aa20106c43987a52f25c15f7de415c51681610bc6bc6c5803c115f11ec6a95307d27257d912dcb501291eb30991ff5efbf1752c47a3c1234ba4fc093cd00e270ad8e3dfaf7160fe78fc9f4ecb33ab4f82c1385b38b1734ae21d60cdcb16741418ffd49e25fc7477b04a5b3ffc026f024be77f6e82d763ee978984af738418ba310cf67a25b94342c48b12eef4fca0c96c3032a40fdd1c3495438177d081cbcab4db401e259ff7a9fcdd32fdde8be484d4fd717ca3ab39aec46895ff45a677653aad01a6454b822f5b729aa9bf35fedb73c51c345f389de4b57c71b79b672148ce5bbfbf001bf118560734b869aad3b62c399482c935f1415dcdd23ff4573f431736590fa95352459af33b8b7c3eace02e4e08e5e3560f3c9f7eea16572f187f7864c0937693ea369b6d0a52ffb746b430ef50b639baaf7e8c073638ebeefae315c65b10fa9912ac7a296f48a74107d9053c73227374f58e6d955a6dd86779c6c055dbad61659449018d7a4236fb320161cc459bc54ba9b753fb5a9dd6b976e862bab4b29c469c33a0dd70cd4012538cf054b010a843533b4cc4022f2d32740c7e495b55ea9254a4ea6656d45974ecbe6cf2c09934be72f2b14687d39503eb44ebb8966d363d0745c4ea1505e44d6234d6ec352a76837c95e350cf4826fd312316721719af95b381b38a227f7ed9a080e0030320fe55c28a7dded61de1369bc6949df4d127b0d1918380dbfeb6de68ba27d39e84c786f7a5369b16a6eb41ba1a71ba2dff0382b5941b1d27c5c4f653b34613786f255a9efc2533aaeaf4a047ade3e84032d35e6bb856656ebb9c24f8df48ac5285c6a8326311c4b17f54317f650f47c32695e072e408cd9e4708b1cf03bee2a850bd0a8081140aac8ef9300d766e2a2a4fa6864a8539d36107fc3b91fb63d982c8b99b924feb00432ca11f3d58dd27af83738bb0fa0ff9b0fe5ef43e0eecce30355f4553e8bf3e4eecfd0e1d13bcde61c97b6dee01b7b1e3d503f4183f2d9e8a63186136d90a78224bf5602c178f3b74e61a7a00d2c8702c6bfbdc4172e52ada0dabac29f9854cd4ea3e2399f42a572517c706c0b443f3e356bb463764e1538e6b381d76ea38af5effbf6f7c3dc8bab66d9e766cdfe883c85376a4dc32db84569077317752998ade145ec1dd6c73fba31b7702eaffddeef529ce7bf2d5d7515fdde59be496c650944179c11ad9d382aa1a0400ae1002b47853c14fd4a7d74671b35cbdd0db90475dcafd840748be12e573eaafb4f572446943b49234261116923973b84339d77f8b60eb294d147ccfa2c4d244c62a9d674b9bd0956ae65e397ef8422dee19122d5290064354e00cfaff7244affd7b3ec7e52a57fce7d4821838627a0799d0c9de043b28cc99a6aa3f187f6db854cab4d6ad63cb3ae681a6374b55ed6c48b653ba24d0a54656097207a39ca8a7f3451942ffe5d8bfc5cc2dd31c6896e33129fff8413f5f8e90dec5840bd2746473c789aa4d7f9f56478630b84ee34f11d9cfa8a2792e82dbbf576f07dc94acc5588f713037854705a32680bfdd2bfd7d4ba0c0dd9c7de601ff78e1d10ca7345f9b85c4ba3a820a8698220c1f17a0205c6fe7c2d9984e89717473d937b522b8a890f5260d39d1a751e4e0b48046f380135c50b80ad5d2ec2bfac592002feb14667b5439e3afac45c613ca98f94b3c7426122e39bfc3f073f5434f0c089b2a0cf4fa0acc9ba36ac97f763e9d8277c353a975b62dd0bcebea8244953931ab5ec3133dddf5668e7369b3d3cd4dcad026d239008f8a61a33ae6fb5566d4b67ae048419041cfadddac371b93a818ec4da74757976816b89e2a58124b7d06edeb964e5ee83f09fbc44d34faf71764a1f11f2f719a8521031a0435f7343d7cd330723c25790138f53e0897a9a15c456fb30de3bbcaad172e842236ba4df244451849fa3469b0b9473b3f0c67a0a18bc613411dac3c0e612250ea97a164e33ae745131d171fe51c102e7c8f57b39c4cc47ad5e43259c8cb6ee3822a02c0c73ba62c69443d41d2fdbfba866a5358a8777fa8efb5ea170863d56d21c93296588b1c341ca648bc38f08c2fff85bae38ecabce6a9d889f2569480d5fc0cae168091d78f329209b41f88646f40c297ace830b4254b2a5e2a00680d67a7279eee70a7ee40dac52829213274e80f1db7479e07d596cd16883c16ee4f6ee62af8d94c44989d5dfefe49ed5d5ca940d52719241e4cde78b52df15eba67d4d3528307ceb7e2cccacd43addf29f40870dab6590f00974caf3dbf8b6f6bfd598ecb146b27e2f8eb2f66e47406ed4c28f5d2f874e9d5328c3b3bff360f6d6415768f3d19d450adbb0668cedc548582306a8c621dc669d78b97920a15378bc789ab4d4a10cff4e17bf8f5cb4a97c65b3783d0481a60c43e2a51b346be20c9864c7a8399d33cc86ef09bb2284ee598f94a9c29d189f0ee37e6dd25b84806b16609df3809d15a9298258b6f076fdeca973d764ca4aeee35316d391d42e6c4da8dc5ccc5cd1a8bbaf36c2865f5b231a79fdcd3d35237c9f1afc98bb31dc466d1f8d732bf92583ab7e75413db2db90133ce860b46d4a29097764cee222fa3430b305300068af19b2d0ba0802c95d4cdbc62f835ec94fa62276326d58e8e7a9210ee7905552d1c1de304505994407adb2f90ecef1d44812dba70a2af915fb5d3768f6e36b306e102c1dfc0ddc004813ac844a3611744ff8ea36bab778ad7ffd02e683ebbd955495e5677d75604afad959e697af28ed0bedf19042605b38ff192df33ffce309672efaf2d9e3ceccd0508a529aa286e2187339bdd11fcd668b39a30adf6c4bece1b86c1674ab4ac6a87c923ca00408fd2ec01bc74b4688ed38a1447138f0dda60386fef9890fd7aaa71c47922d4ed979aad0f511c2c839beed8eecae5172d1fa5cdcf2d77c6fe24daad30816c20d6df5e94c2d64d22104549d4e8bbd2bd216b37a535a55f3ccb63848050521488786293783742c8909109c7b1d9b902d3c82534433ce06ee0c7a6d0a5f7649ac12be34afb8e66b15648e7d64c7beba6633352833c9214bbf82f8db5a04c04a3d524e927a6698c9d4008e440ef72b651bf509202b62ac85ad5f39f2ec27f9db4ef2f13f96b15db523df9465fc17b6b482ea2e0e4fd9c89e54f25e7cc24a08d39b3c762c1f62ada53db865e7590fe66115d3f60588e53682ff6586999ea74b8ffd5f0d3bc2d2139092311b0f67005cd89f9e97c145ac54e759bcf8a2536ffd1f77d3efee05b76d1ab83be6c1b796c191eb1a428f52759d96db1babafe3594df63a7068544352c6c91159c94e9e6d0dab767940a1f95777e4e564fbd7229e9f6e04bc0d32422dbdf542c73ac03fbe16583874861386be81bc6ddeca576371ee61d1971c3ce5af1926fb46f1acc58847f901c498b0201bd207fb87a089ad9f9095e0c5c5202c1acb6c256e387dcbacaa8dc2b87e3b24247ad0a82ae4d7e7d115757865261fe4b82fd527634066d255a93824bb0d82d390e56dca0df6e7f75d04f262b775df2070cc3b597c907f978b0cc01b4867840d27c5ec5bb05b2d2bd255909851114a8d56589b40a8e7ffb1d951f0b0a31f3d1db1379c7051209e4975340cf0bf89a20197f25f6e75ca1a9f40a22e3dfa945cb4c3b08a04c119656dfc389921353c0d087d9b85ec1ec513d2fbc23a7a056738b3a488dd07a9b008a400f0dfd6577da220da51347b31e539633e1d1c0faf8ba66c00c231261f62707f6b5b581c47697ae8e6ee47e14426356a10019e7fd4c6a33e0c2f466e77b63ad9f71d1a22a3445e7afb9d2c3b5cf0c30f7782016fe0be68a1fe0314f0d1be0a6e73e32ade565e3031fa59e081f20fdf7558f60ff943c8d5be06efc6bfd0bc84d5b6ff3c9f02b52eaa886c6404dea3125d1768ae98d42201f4f1a0a505c71e417d8587dd927c371ff93b8018d708d5f42ca552d091beb88d66c46a6e51670432b00d569ccfe4f9aae35ec0c5ba2c96162e54a455e110865a2578decea2a2a71cbfd12dc0e1390ae5eaa88dd8f706a9911ab75df87b47257c658fad57d4f9cc8d667b3d200a0d543854a57388fb20d0f607dfa0dd789c444d2ba5e693ddad36f96700a577e729ae1c4deb50bbb63eb0af0ea3ec81b76ec07e4425d4aabd366daccd048cdf7698e7910346fd79af8a58e82e3f50233f0271dd2627bac436a0874e36a1d438f3bd4fdd5bdd7e24d82f13e4acc1d4a62091fa0809293b3ba17349f99499eec04cd47d027069fe7d545c27e4d33d6e504fc268f196ae4b49920b3f606d9e0ed3375593ec2f7f34dae86938722ead2a795127f4321ecd8df4b31ccec7c2fb33136e42a9f1597e54c78d38cea120b770d68d2c3781b6fb782ba71de5f6bbd46f7ea07def80d6bdee9d078ec6250aa9def8b6c97288863b50ea3d4fc20a13d3d1c334297278e26d27c7f40ff80f9d728e578ee4ddf8b0b2090c91aecf84ae7e4735a227add085445ecb4f2d969db846d5e94fbae378e80381c6161697030b9caf7c4662e2fb3c8f26c6ccb946cc04c2c8a7994e585272df923b8035ecd7edc05fadf73b0376c3654735fb317acdd9672f17326739c644c17252da09470d3e61eff100835631201ab601a55602b98b46915e80a40c8b1819186f3970d2274675b5029b577e5ec754c0df5994645012c528f14830bc3a861b878dfae36386733a80c18c6db708200ab17ea810ce021b01336af88c841f04b8f93c903f8572d0b1fcb9c16c20b914b0f2e96903d0192517d859b33af59e3fc6445566cf30a93bb0ab06d2e2cfc2d3fbee796b5334f2d8d08ec8863b283da5553051f30d70d4e0533667e64b982461c62a1e1d74a09113d164786f5f2e482e498b6aa852454badf31751cd3f794d2ca9a009eb5fed4d29ea3a4ae9bff6abb251cd170f3da4222a8ef5950fcfba88b547d9d9b124f45dfd6c097e03345ed0bc5aad453a6e513e7985683383c795504b3e270a8c28586caffaad4be4abca948eda3b082010ce5ca8c5c4a927b5a31812d22adf59902ba8d61f1ad8c6a3a91269aa6652c3e2b6af77b149b4f562c682d269218badab713f598233badc0a521d9c180cd6437c7d3925e526d854d322526a33ff22609ddc144c7a2f49d505f5d95a6587c67cd9cdea10b7ac01f3d4212183023fef477deac5312bb583ae9ef13bbd370cfe193d4ce7e70932ccb997c261de37037c7e78531b7bd4574e8062e8125ab1e592b8573dd47ea0c0dea84cbef9a33d026208f399b0c23236e22c716a3db372cf4aa7b574fd07c2b592fd95da696d7a44abcaadab9f15226ccb14ba20beb84d7fa0cb78fc33447b889e6adfae2e84671939e5b52887dc8ed86280e8eb748d63e367297d1f24875d3fc8211e4bedcd357dfe42647df79ad3831af6bdb92cfbf53f74b802d9703e2a72dcb1946bd21d6cf45632fafcd8daf69058800782693f9ccde33a98fe6a3d850f75a853eec30145ddd9d09aeb85c2adfec1f2a371117550eb423344f1e539f42b470cdcd850b4a6ef7d05a7be13714adc2b2d99506856ed57ea956c255de2e89967ce5a368623c99e21c60b56180114f998323b60a963d5184fa78867a68d344686fe68152770f9c525a529f1fd8b0084908d202f593fb972612eaafbd75935b4ed931a71fcfcbd449cffbdf97c149239b40a41b59b1034e3e7072388dfbf5c4657ef528fcf81a497ec66035275f61bf86b0b4b8169a708bd520d3eb365df6b0251051b49ee3a697ac22726664801bb522a01400ca655136cb4da316040cecacf1ab44a66c37fe9fb2228a8a4ff779aab956f34ca211d4b117183b06170663073c5874871deeeb10759e6bf05ace9867a56241e4e5cc1dbfc112ff6694c8fdb9e76ad73ebfda95a2ec835d6e95f9af948e1007cd900bc292e094efba144e54e174631535c24a78b9fea3c7ce6f46427bb01e52abbc1964c5c236e7394866114fd2969f59d05a07beb52647aaeaab055752a92bfd30886ac98155687a75108612f93bb16e893b7d01ffe185057ac5acd19e7013badbe8841de4307fc4996c11e5ed32f1a6d27d9d601e430a8ce3e9ffa6933358796ea6c9a26ef32dfa159f8aee31ce51101c962e7bdd1cfc529496ceae665613c35e4996ef75f21746e4e78db07b3734395ce09425851d964bbafbf14910bf61ade6f9203a3aa418505239293871134ea19fcc019f7e9cb8cb4e0358aca9b3d880b7e063c1c824ca34fc4c45a017748b71217c9634e71ec6628c0e4e98c44be84bc394093b903175c777c6bfb2eb18d1466dcb76eb80c73a1c836b544fa7a431bef6db312ba5a53a194b2b7f363d064a719a627b33064d93c6e6e18bb1187559b2364ae1bc75de5af4989e786710e2441a4f6a49aedc0028756c5da223704e1626f02a9bb3381ead31443ebeedd7d7879e8125fcc204f2c9114efe881c29e3307b422f8620d007ba5361a9705a9ee7af5814585a940162dd7833f522866d286bab9e752dce74c70b244a335c29bce7ad7bf2d770488f9bcaf94c0be4a84022d2a59a3916ea66c552a7eecd8731ebcc064b217323c3c5e89a9c1cd233e2cb0b38ec27680ad6c9132fa249db6ada6cc47f86cf44ea31605b3dab3350d113ef1835212b3899a6a81b51214838ffbf5f5346b6876fdd4a4d2ce05441ccd6e8f09e1fa05e7d3061c83031e263c72066cbb62a599bfcbed9a8a6527a11ba48f7f46bda550ad012ccaa284c2ac54bde48a827d2adf2d1dd7f51ca47adada8308f962e4b26c900ffb5282dc5d403149888b8aca228d89aee757747d83ff1e111e0f23c4213732922b87c8d79131dc7b822490376b6b948d1ab46167f850357f411b25ba2ad49b2cded93c222151519fe1be40c755739241f16b36be4198ecb78249339b1ca6bb8f3f70451794718b608ad14af77c7e1cb5ed991252bd14dbbd0c79dea90f771cbae322640fa17bb3ed30a67b19a31268e0b1b5707f9323dad7a3a187e65fdf83db5f01beac5ad29d4f5605ab81050119e66729b241c07a7b58bd803472de1247e123b70e56eb5da9268cd408013a267b53b5f8dca72346822857c18ddb128445bf8f2a6729c581d79307607b555b66855c90c954e2e1729c3bbd6c9927d4ba9cab1e7568c556d22a264291e13987481f19856c6e4f53bed5be85c35428194d710790e560f66b3e6803737c33764d0a607d25df6f5d7b2b21ec7db7e169854dc5b93e7d17286522075e112db91adc865521d54904e13418933517c7cfd7c7529c82f92a24749dc2177569f4fba755d42727083277461b0873bc16b69fd8b0d34eefeb7071ef07c6d83ba96f7d72b85298c66fff16d7c7cdf0b372f6b0c36cad352e12c9da5066128eba4a33b28c93c39de5bc101a1abaf616bcbca13479986ef9303c5adc3533f715e3cb5bfcd7cbd79fda2254d0437742ca533ba0d507ed33da77751fae8c51c2e251dbc63a04dfe33fa323bf12c6ecc37d54dffac979c798b7aa77d4fa5ff11b55626a9b9272eb5aaa0d1b23f91ecb4b114c88e009a5a47c4992d52361250fcd17523c7ab429f22af633ce58b35265d918c61480c89c0803b2904d79c416b8c8902568edeea4b4252ae4a81a11b9d706d5ae313f7fb82b140f36e0c5ccf401b672074f34ac04bdf43dfbc0535717574d65266deb02ed27e29aeee8bec97cfe7b8b27dffb001bc246e844fa2a8e0eb77ee8d261c3f1596e0e65bef6c20823f27f83917e2a94c42ae487b76229dd004d07d844de344330b4bff3a1a4c03c8c0a2cf1bfb316bc69cb05a5e0a3ae2fd59f21b4f40531c2fd73b094e26599bc94cab622f3a2ea9019c3c5c19d8c4a4566b393a2f7e8856f0adc213dfe00393d1371e42334b84783901e339ae2e363d6d14db6e835f8cd7bb33974bf9ef0951ba47c8d74f289f83cbbad9a6c23b14293aaecb6396ac28c0f0e617f9f9d24659019de95bc66012797381d08654255b0404e8d5605df46cf9f81f3d3f3267335b9e98d2d2b94fe2136718101d51d033ddb897f33d756cb2cf8dedab7ee2a42d3b2fac2962b137d093ad6e9667718ba6481f56f35ef1094f92b7e489f3e9d1786171863c0c6775a8fb0d64cac9a51a788c81d14098ae9fb24d038bc046571d009222ec81b2f191d55a89de64080a70d67472fce51f39867f62d0a1ccff5da44df8f9a96cd02a9f18322f700a4a6317822174c6207723bb68d99964f0ce16d5c4426042516bf1a658c52e45fb482273871582e22e47ba1a610c8245d4d2f10947dafa3dee74422cba77b63f4e15e3020dc0251c549925b71a4969d4b4057a3cd67be5afc4040b74066bff9b7f0addd0fadf8670cb7b642ac3d2795aa70dba1dd8eb4a09aafc9f6690c9a688bb90eee613bdfa1d551096682ba47bc62227e9035015b66034a6f260cb10f63bfa0f50d22c4d7afea02e8f44a9d27b04fb2212f38db8352b1a3c41812891d7b507542b89810bd1268532a89f379b6da4df4d57e8ea24bb3d81e32f41567a93580db01c7ce9509c9571ba06edf5dd703ec7bc528f6e5b1ba58fb7267a150a7bcebaf443b65938108bb18b6931d2eb9cb54ce8fa7566120df149edd8944c33205897ef7794597a253d3d7febe5d04d777a2c56ebf6d897bf2077aa059d4b3ef032ceff63c60b3e0b39be0ffe41e816d2640d5f2a5e1956562f37dec3828af2e4d41eecadb3854913014631a7b1fcc183b6a71c5f45872500bf61077732cc75faf6b25a0077b9df7780343ca94455a3bc79e91c35baa5fefb00255c3c4b5ed8aa4ca63820039b9388b31f12843a148994acd0469062a4551bd5787485b82771fc8e32d46aededf9a7d1a99c24e6dad07db12e634391da74ff47678f710649eeff440640f63bf9bc9cd757c499190e61c85bc1f9f76db19869adedcf9ffa8639d6a1142d7d8339e216673be47e09975c108d4d5c4d04801cea28c5d69df2c68f796a150364304ef254ce7d601fa02f76e89c8412f64a5ad1cbec1a5e94b978b082e7d1380f41abe4a57bf8b7f8f4c90b98cf7fe246e2a9bf1d611819e553965e2b37251a324e7c7dfbdc87f37d1020c6c7fccc53286a318f191cc55d4f0bb96200d49f9e06987eb313490862f3c25b3e8471b79fa789f16e9ffd7bf48a46089ba1185a39bc09253ae75febdc78778e939835d1c98f11e769de9611c561384aa349595be60066fc9bdb3efc246bffdecd0e9ead588fb56bafd919647ae36f198ba98e7e730c1618fd139d35960901903747f6a036131b9861ee568cd942a6ad0558ce5a304cf71b1dee1522ae945616418b3f13df65ffc5213583ca2bdfbe92bab29e44f55fbff0fba7246dab9bf9bb3f90b2d4ee68d52631899d75c1c923fadace91ac5ac38384bfaea72528c13f67d3fc76c5cbc1331a4ee3af15b0f62a989816f5e4821a21699f0c1281946c4e30d1884a06f4120ca449296722e9e5b218d50861d490579c25a106e9262418d0d67a070b2314373eaceaff9992fefdbead46f26b22d5bbb22dfb67929b345a618c1c236076b9bbeb247a1e9d53732ca196989ed267316d017e4d1c6aeeb7750d5ae72c59158761f85b3f84697ce1f90dc53ed63f4f6b38137269ee01903e8035ad09fd79530251a2cae0078e20ecb14dc5a5c73e050a94a4c89dd229856a8bf750a646a09f99cbe2f62105a9d4fcf0590c7d60c87afee850a80b940e2a92ac1276fac2857093c5f99b80c942b72b4d10ec8c28c6d0415d1f6e672746aab7e36ef817e08303b59731a9ad8844ea5458907ac7dbedd5ef9419335a41c45013392dfefc2cc093a932f71725d2506c5fdf77e6438e3525a631e81fcd667e9053047197e9906b413ef57d27c786ea75415113c3bf40538d86ad233748fdf65e6ad970925c9661c796e40e9d86a343522511b7879aadbb19e7329d979f6b071c8249ffc59e3069b7bed2569a04f919c8b65ce8fc16bea035ad09dca37b0932d7728ba5da0d726f334007798d208e14627b218e0ab33bd2ad5917df9873b0d27de4ba083a7ac8a16e22fbe46f1b6fffa8f1267e59f8821789a4ca870ca4881f565d7a8421529ceb4245908437bd46efd5a7449dabd725b87c8216dbe950d7b3681bb66d939404a5d26bdd39f8f56a5160fe2bb6787c63e8bec78acf65485d489bb3077c3ab703bb0a7f197242cf8d373266196f1626b5f95a330d594f18f47ccb044b40ad308ca4f6bf822b9f680026b574086219d903812556dbb268c1dda6859e6ee6ebcd6617f9ef6fcfe61c9c184b92f2067256ddca8f12d6845f8b0363ddc52d9c1a18208001db50436250557bb86ee04da7539b85553bd418d9c6ec7ba41cf6799adf6171dff0301c1e388b77c61ad821aa35f7ed9a25d92fa641a14ebc0f650b9f040ab625e47c45d2635be778134e6545dd02394451b67f2933893fb1e283770fcb2228946b42d5316fd1f5d6e2e19d843dbcd5b18b7dfb7bd71daa8268c9ce2a817e7affd30350087d59833f1e92e81f038868f0a1edeb0a8bce21a1c8ef5f86bc7914f4663789b6e70cf36c73ab6e271c5d990af23480a9fa252a290fd39cfc287d7c12045ee168d7ce9f29c099c3ed9c17e00c49924d887948cc837da4ab5c62dcb4c150a6b3c6e37ab8220fa9498afa19d429893164f81ef2def745d4948a24b6376bb1f7176d926db11401c1c001fa0ff64e0720fc546f4a4205e492804f02fb257be12e9121fac62497f573616485f49623b56ec5df8e3a01ec413c03fb11d4484ad27d4f21943f7418d6c70a236df22a726833941436f47cc67520008e895fb4e174dd4f56eebaad332f1097c762a1655f0e18a4d648f923e237ac7d827c4cca5b9558d61903bd27145faa7483a1b5631784fd2c895ae6ce073d6135947be95b725971443a0fe7d784a3dce7d253eb9fea3a2ce005bf50ea1bef7a3ee7480209a7a39d452d3f0bf126f81a96a6944c15e34d24a59771eac153b2cdee83a38b122ea17e6ef638a7e25dbb9a3f4191a310391a76e722cbf22dc432b3836d50c363be836c4ab6d312784d0fd6ebac37add46a5dda909c60473418f4fd67e7cd3460720fe1e85e79ec70706f444030b55084f5159257c6f2abe935ffabcde5d5640b2a0b6113a3df1ba038f985d95e9617d77cc81f8756638bd5441265a074f2475919b5af205b456addfe3ede90342f0fb4d5c488cab28585409bb37257630e561030aa7c51f4358796a347442c1557eb90e3a952a1bf1300e5ddbec47b8ae17d356bc0eaf652ffe9706cfcfc1028c183d524c9a7a6e073a6ad2c1257a57d673b34458f52b9a9a39eb734ec7e29c1c70242125cf479d4c09f3befcec2060d9f470f5b365d7c3b84a8961165dd120f354f1d5f87011b04f67b9b536938883ac2d3dcc0bee5ac2a04dd75eab3eb1a0f0683289242a3e103b0aba3052282cd986ed4262a3663e4f7a46d5c7a946d57b0428b947aa119da04d955ea0897f3e437e02ba24f7f362c0f1655dcb1566f4853de17951977f1e7bb09a992ccca2fb35b6023bda55a18f686330fc38ef15063eb671ca1e88b00e359eb9fb4e49572eb6d3cd9fdea030206313344e15126c81c28f5a29c9f546633280aea0b67f9974e00609f6171f7079b9fbdb7bf872dcebbdda6ae0dec2d122823d9730a4864a36776951c3882");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("HASH-SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.setParameter(new ContextParameterSpec(Strings.toByteArray("Hello, world!")));
        
        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    // TODO
    /*
    public void testSphincsDeterministicSigSHA2()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_sha2_128f, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initSign(kp.getPrivate());

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        byte[] expected = Hex.decode("e8a1883716841afecbd6f9bd8648bbf86ab3badcb227b624633d51913eb337e07b68834818c993532f90581ff8e26477449fc5f0fb37c9d8462bee7d3f5825316afbd4c9a2a266d71d7f8ba4db064c665e02e7aa0d1ba9bac5d0ac0934db69fa09fc85234a701887cfc0af912c7b5d3186c0489e593fff2e9b5c79a0a77ac312aac4049d29ad57db8e86cec1c1264e819c5083bd03b4ac44b94be97756e2e4b491947a2103b371c1b54940bba71cbb7f9bbcc8eb90dac25795d1148fdbdc3cacef7945bf9744c966cb73cde15b98721440d2fce6294e77c39bb2cc37738bb2c2ec45a8d64a7fdda31c2a5f38e9cf17afe942470f1227e05b907ada0564ff9cc0e1154b1459f4a4b21485d901582c2cabd443635262c6a899e774e27d7428d980c77e2d42c15bf9f45b702462dce170042b696598fa8a850beed7517f717cb48fc98c8634296e3b8572284717fa5248eaca46c8b20670c31347b919d6569d351e4ba30595a5adbf887c8e971aed2dcceb4593ad18db1e5f9226ae82366e5c99c44e22ea292912d00aa6c53670bf6ed0e969c56a95015b8c5e0641885b4ceaf45bd2d90d5b93f5b0f63a8798a572935e2300319aa40e6435441b611149750638e3894e66e7c3ffc6a4f1cb37456a7c82b05e2b6d16f8365f05391f25539b835159ba9b775e85abda82d16d6b7b626f76bd2e98cb31b82ba8f18f0309c41677c2b4f5e822f255dffe17d21e7ecd421cecdb7e6a3f88e4d76fa0eeb3d7e9677c0c983223d029a025a147399ce72a13572edb7d2689b361993a06492df19fc5391a1e6e89d4d81cb5c3eaf1396941f9a51b8897cdf725ae8669f2b4b9435277ba13899a8f1805b77fddf5bd6b2d6dddf02a185d10f3196c571ab246bb8e3e1fc97b0b0b4e1c3e2186f6839b615c210613c4c3c7fd922d1907fedf6631bf3d1ca99914ad5c9fd34ca51ae4093e2a925c6a967b2c2e8c97fdf73d8dc3c6fb36ae587e50e0b31455f618811162c30ecbe1e2528d325a8c75afb13cceff548863c535bb6f72779fc150b74d33b4f98f7dca144fa554318cf48863fdaf16c73ab14e5c00580ff227803b1c8c383713bffb6144ae7b02f0cc1113fe2f57b72b93edc1e0c363ad4745e5a96bc61b2ebfe5fe1fe6008e734fa9382c0b818834e22611433ca213cf090c5af84a318cdfd038d8cf6936479d5b35dacc30be7b92e13920c0f80e5a6365ffa3b0c35ee637a4e861817b10b6c6b8f6532124c45289ddd027365e86e76b57ac42b6c15abff1b0426d1456299f9585b16aa0301d333837e751db28c0e3ef942d577655b70219353954384b649dbb4cfd8754d80250fe9ed859ab8d51e6c663ab32bc6c5972620214f3e08b3275829e1e97a19e2795ee39a43e56c1adab144951ef5b1cc1512eb250625d7bc18165a20e588f03075a524c0cac05c5da810632680e05516815c5b32262eb5b3b54851477edd61ce14d3238c3d02f4518d809887a49d148e84cdf7e50e0c06d82b41e152a5151a576c69fbc812c327d440b41edb75c02ab444ebc7da11143e440cfbda9c6c7916264b95692029e4c1bcbe56c55bcb2af6530131147de4a1b384b46179bce044dc104a3131ade59e4a1556e665d6ae0ba1bfcb433215d6b9d5be7b023045b0b49490685808b1a545577abc9abfd069aacd33863c2f5d0daf41b4c5af5224803f248356ca7c1269315c1bc4cf8256cda2e1dd2b1f227b7032ac29acf80732120ea3f9aa07945b602810e8aeafccea49d32e5050f248f72f3fc839962ae0e1443b46b586fbb48a2aae82cca180d580312f918ed208a2b6a493cd63b881a75e321a5622bf47314877bcdc9474019b5c64152e003d857b9eac87b3ea6c8f378592078326a4cb16d66caae17694b306ec4965f85a064175763ac9d4b457be3609188ccbeea07087f5051c66b5ca51fd88fb91a1dcc3f93ebb7840645283595fd3c4148bd62e8dcf0c5da4b89492222106228717ec8b473f7505defcf6da41c8e31965c76a067604da9f031f0b34235d7ef587748ba03cac0f104ebd1d29a44e0ac96c85359550a115aed8a8f15536032b6fbf4ac8239eb94391b2f66d7f001114457a938e5877f0eae1ad36ff6a853d96ebd8d5e44391e83a940fe538dfe2caaebcf7b6110cf4e51617f3619480c3396d7c9d2af597e113acdd794cf81de24a21285f4ca9bf56df99e02587bf89674e7db2a1a06cbc217940fda6248befcb93a3f947234e59ab6b03333932c015dba3c88092f362d0baac5c5b9f2d9d5a829dd3ad4644e0cde89d4d8df4d547187d66179f7b350112c4c004e6afc97fc97793530be06c13737386ba92b13cce0c0b6cb6b0aa0d82000d674d1998f05b271643ba85f7da6304dbb6f530d2c80c40c3e2f925b87d32603e377b3a9ac486e0f0186c191f4648fbb8e230f192185498e3e09e82d321a9a6058c553419e21c3ddbf147c2ed88f99398a7eba4db3a7ea39b45693285c4d6d6c8a1eb8e7bc0ed937838afd59d003d69623f6cc6740f2a7b1808073fc7638960d649256026d9b714d903719ac7959405eed2a22e4a9d72e33ab6f0aa5d07be4783b4ddf36af1b4d4c78585cfce80738b9c1225660f5e16d9de5c9ac285d24db80c9680525d419b626435fafebbb683c9b36bdc1cfc185cfe87b6ae93a14e3d63db6688f300154f288484c07c97d82f438fb9281afe6254170ea6d8037108d8984e88872f1c9072eaa46ed6ba426282ddf6365f010323e176e11309a3d80be22f8aba5cf93dbff8658665a9d2e3b428e05218d9da73aa0324f9500732920cb278bce651e21816c61376d1cf6d2899f02423b33be6a8217c217dc42b1f97abf8f63ebfc367b4fbf0f158a32cb2aac06616446a9773f6501692cbbab803074b5c026cb3b8ab7f48d6e5818e668198cc958b8acfd6469e8b835aca0e5bfa5a8f301ffdea73c8693f6c656cfa411e7efab0842da13aa7132db26176c792fd1a99c79551ab99482be3674bd2e37fcd8e0701f2a9cc801b56e717c8186cae04287fc741296e97c5563c4b64e7d36b76cfb41ff3ef32c5c88a4dc09ff91a215d157fcae725f7da8801e72086e3f063529eac6a11d4845c1eb0bd5845801cf9cc35deb27d7bdbb67055f641b9f4bfaacc0af6124853cee6cc3a858c1b102fde6da1d245390d6a6db8492b1142fc09b90d8c985ddd2a82e9e79355a070eccdcf125ba45a2543d473cab41cd9ec464b77fd57c54dd5b346f954b1c2acd37841f29f9b7dfa767fd029bddfbd0cd3aa285540a3943c6d1018f4cf87fd7c17fbbc65016d5668d2b90e01f3176218160ef5241caaf3bbd747c81da560d1debe3dc258197740839f93ca6eb41e7e635340e9de07aac1b24c5f48182d0bdee3672097d2ae48960224038c8fd710845d0927f647dbe09062c586842d31e1018950a3e16ea5d209402367badae58d2344d169cdc05f5a47f86903d18902ef3bed7d3deea961bc2e8e7019d77005ff88be637ed0977354b26ca98a7c0dd436af45341626540e050d7f4f03b703f254e32bd9a3d2f93997052732773c2274cd1a26da956105c5fa59dbfb002efbc28d3cca08f91f0fa76289a1f68decc6f943cad337f710e26e8287ced6a35b3c4a5b2598162fe2412cc2d44b49948f383403c23ec22c585e95f91063202da0755205bb592fbd345e10bf1b545187a7c14aa88106bfc37bc05dafa17f0e2bb8edc2179b3093bb1cd955beb621d2e222b39af3cc1ed26c7067012b4fdea539c983e1481b70dea56506a3ad912257cd7cd58da4cacfd4370a0dd292c319f23ee3ead9695bfe91c7e83bd846bc186b1703061a9d4a69eb961ba06415d4dfaf2cfe839337a6efa0e6b4f4a23c700f678e517a64e8a0c1eb28c6044440f203d9eac89c8b7d406a076bcabdce36195119001022e640155df8ef46241ea50204df095b96deeb70c2306cea56794e9729b3fe27e114a95344ad4d033175decb92e0ac3a88a16e5ba32f8c94853764fc7aeb16591cd3cdeb84b24ef6827a341355e7efe0ef360991a20e6ae77a04d66bee1da160f14ceeadabb7844e3baec99a057202d80f41c01c6f59d6affe7497b137f93e377e3b9f6df995df70480098c46a85e5b9d9b3fb7d4b7c6f4c72e1ea8fc442f92d4d74b41ce026aa5ecfac54ca2b4f45995799330082e0b558f18c5e31e698c67f2e82dca0ed3540f8493f8176b9163633481d4a444ce792b1b5b7c1f390853aad64979678de457086d7b7a0c0230ee0d0c269322812d5e7dc8e6e1e03dc0c977e81a6ac37b328af654ab070c6b073e3d0194046e9e91898e8459b90faba6e0c5a14a764d919db650c798aaf27ef1ef87a62b3b5d0b69a5abd7ea8e12e19a74754deadbcd82867ee271340c0687e7091091585e1163da7ac9655c91a62da7850478d2283fb6946306834f2e56025d863044b564818de7b43a7d895bc3b260f4d8c55fdcb09d8d01d11631e7409e3dffa027be768340e5a1a71c518396906b1ae32b44b08f6c0b54ca53c7e73375713656815e503a799205ef9b6753d177794c753ec2a067421a13272d09131fe37d212c19790d707c327146823e7442b56bca450f3de89888637e0dc249c2e42c6d6d47a6a49a27dad3aa5b543a0130d7d34f6310bbf8aca6e514be50e2cadc80a7133545d56bfe06a017191e5dd5ed598ba52bee9752896c65fcd4bcb9de79f7a89d781dd47601df7445e23104f2d7f9341d6c1e833247b1f5b56721255d2616e6edf75aee159735f15a70a170dcced4f0d029800b6462fe50379eec7119530650b4606ddd7721e568e52a934ea14565168c45cc0b4e540149badcdc1f70e3079f2adfc8ffa44333c88c5e875e64377780a23573a6f009d8f8d8bd3a2ec814f9a5636f19dedd93b0ab1f70a4b6666520d7b060925c95c2725ee065f52fd09b2f3b2b89201de0174ec755680cbba3e5828298a054bcdefa112aa739c554f847069ec6f4bc30c099c67eb930a68d20a01e5c68d12b9f1b1f3c557fc9ddbe6083aaa884880c95721c85ab22cbb5980bba49c708edeac69a95f7e0e70c9a75fe011411a1ee730f2f6699ae74708608ce6f33435efa0b31379f6c8bc2494dbe7145eb70f6d4d46f8d7827071c49d55c487f9fbfe1a56a7db761cf3d314205a18866b872aa8b9f4b68a930dca64e8fc294b6d59eefe25cfc1008689c78a1e90bca877ce9f46aa05f81e66a415092ef9bafff8d4732b12976b925bd83439e547e3df349eaac385d674bb2672e23290e5db0784ebabb24bed7831e9965c2db3dc8db4ca4c3525b3b132439fd0de7fd1480e2e697c2165e1a27b646898c1af610276c6f58fbc84104a345783be38749ae3f968c980e368b6c7943fcd5a3fdff44f4a44ee55cfd7f94d0eac235dad9296e979f32d5ee4fd624aaca794bf5cc30584e505382b852b880f6aff7da68d4c7970dab6d5510036bb453a7462d7cef59fa78d03de0ba69b266685dc2f17ce8e8a6c23e465175b352c977eacd5fc611d55a03dbb46a831e5016ea28329373d40cba6414193641f75e27a5099676670634008678c3b5d1f14e688a1196b08e4dd855611e56fb74146876ee12b6d7992dc34bfaf68462322e0f169e61b127c00b9c8817cdb59bc675387f671e913d64662128134932a50d8cb6f49a13646fcb10e2c3f1c8c517c5296d1285660549d1bc0ade7c03354749ea811002a9cf526100e264a6f9506c563211e56a811d8ee8eb8e2e917512d9bd38c0c1f51c6968cdb10b9d526d19f4762636bfd9353f904cee43d28b31f6a65266f46e0af9e7882aeed238450a985b493bcaceaf8eef545c93eb6b7a264dc278fd621c338f7dceddd29f68c20625619374410db7d45563e2d90341c475a5df5a5f8dccf3c648072e205adba8327eb36b9d2f0e7dc5ae59933063ef105538974bd47f11379566342c07461f6fce54bd2ddae8004824e93eb63cbe950663d88c31b9cf20e4abfdc1892405b4879cb32ce9c6eee7f93da5e7955d4c04b04cd13bb4ff3f13ee1ced444b80c92bd18d8c122f43020bb423a15142932bf522d9df402a29087bca975a852865ae27a9989a5921ad4345cb4a64f7e9f6aedb0217604a11b3eab8b4adaf2b9f527fc108b3a6d94bf6d0ecc63a237a70489041d1d499316396d67b5b8c73f6e6b91d0a6af32914fbfd860087ef4d14ca4553cea4781cb9b075e47a9fac71c38779892c87a21ebd942a596be33fa3f8473e869d99213782866fe8ad4a79d4d2dcee9abdd53de125a179af9bda9a8b8fa9092ea6ef17b6260da9099ffb1cda671fcc364ad5e40bb4028115be8833c9c6ee381e64c20d1ef056cb5132a04dbebadf2e62f8c545808f685f8f08e817558f27ac120970d6fb1250ae469d33f181ce62aa6a150fec671bc669427151da2e8de1f010c572a000172ca2a140ffd253a48c612c413eac55e9087817b42a468e929e116f4e33a63df26934e2478e806a583493c985f75c4edac0280317bfdb572f1ae1452aa26f3076e7e48fc91a253d689dfa76bb46b199abbfd6c5533da987747dbe90a4c9a8ca664661d8f09df9a2b6648e2b7185f459084f35a3d56f773da2bfc70b1d7ab0ddea709362afb0435c6e6f6a58d0cc42da9a884d76123b6df031accef92a77b67a906abe90abd54ffd358bd9aa977f926a71bc46a5d9b13ee0e4b761771ca5538601cbc7204463f3bc3821e06738acd83cbaf7571abbf032e9607ab7be96baee4ba563932f172ddee5d6adfa4c01b21439e8fa80101847ae4cf5ba289d46fd65545a45fb7f4186e02cf9a0aa2841bacd3c463d6f23ac88514c9039987671fdb263621b4ce663c7838dea4568905a5f1fa3ee4d82f222579ce278e145785c5403bcb37825d3f787ed3f4a657c7d06a77c31afdd33f4042d6baffa3898da308a9a2f367203bf5e6afa82a6d5c428cd8b8bfbf98a505cdd24282867d89d7dcc7ff7f56cfbfe6ed07ebb3fa36ce68ff1cbd2141a656a7e62ddd90e5fe72308c5a2a3a5f198bed49e4b7d373ae4920ea0ba52b3c9d8bd9fa45a655bbad9ebfc64f06a759a79d97f0693f73d25700a7aa7dad283b88c9d62d07951642561911f11e1c7bd760c9a021cbab298b0bddbccf828a2d203a10e36b7dc7d5f40df67c226a9a423f8e42a62a3e91b3ce9524e0bf9d2d18e07e1d0fcfb8c67693168871de6b5e683c0dcf46e95ce63b5887d2538f76078121a5cf124f2f0c06226387fe22be207b8b966b59f12a702bfbd6b00ba9b6d9ce2beec702e262af32ecdbf54811850c51ce03544087d7b0a292a87e0ae406e772bcfb02c84c513e05836ce62116a2e21920bd219d49d0d888156577204b6222e1b017a9bf5f6d57f43011ec2631a6323ee0238e89d0cb2b20b504c485f8a2a001e79d3ef7f56b71e8fd30add6013dddd984a2b5ceed885afd9b59bc639fb2dbc5903acb55bb2612e4bb7606f5431d864a12770f0cda1ab87a9323a40a8db68214aad3a00e3fcbf12d2327e33c658f629edb36355de41e91bc9ab3f4ae43dc43c7f457a28f51eb1e27a34db532a4a869242848dc23399572f4a02d07a52c58e8829d1c1a6e2cd123707240e1abf62f737ece64cfca027b31ff67d9dd567d4ca309f18a91d27a40fd2a4c1bb9297ac329222675d533d048d27909acd0d562589c137d6c0b4534ed1488eebc2e823eaecc1de95f120d2fa5292257c6c0e00b4352fe3da2880d08b7e4594770d2d0c8c5f2ffbc349b7555739226e5fc3c1f1e4effe5072f1fd8a6eb1bedfa334dfd7c6bed3580f5209773d7c1c133d26b758b7132436810f27f497b7470ea735fec626eb95b9d301ce012c8f61aa4db918c38baf9d52c67c0b2add59693bfed42a4e0263a7edcf473a481ee870260f3e8b22a42a820be4b65e797b801a86e2693a3d9364f687aff0a7177a6a3d35c535239585688255a2e378de152b88133be4a0524ad6ab72b539006e21f67cbe460ac56fb696174b87cff050b2c577b59c0c4b1677e5e325ea0b7d89d68a2438d9a2dcdfd898b05327bc8a8fb9c7df586c7659ed64de3032bce462832304726aa0f842cc12a4872172bbb364b5cb7e5d24eeb2d332d15bfafa591c9616363d945f14ff46c6b98ccbdc8e949a5647312fee2b8fdcf3ecbff2d7e259ef14d5beaa0cafdc81d8434afa394ca66769d230811330f7b1f68b6be89ac987a45904fc4e853134d5d3a6a140fb56a5e8decc3c37d98cfe3a9b43928f2e01efe9518a6bb7749dca1d7ae8089ee2e3861151c260c5a484e2f563c518bdffe45b2488cdd8e9e965aeab01bf894192b5987f1e96e18f75266e21e72c5a728ed2995a1605b33e8ecb21a9d56d25938730d6936c701a49a155eecb39075e4da05849c67dae2f2ad40962837ccd03743cc331e1b09dbba32ccffd77895201999664638a2b035fb346d2a65b3236253874cf6fd250666f68fa517328abf9014dc8545736eefbe2649140510f9e669b2e28bed80f2618898bd2eeffa0fb5e7f962f685d42a7f694255a33335842dd5f7f48969252a35edf0f8e6920ae85fd2836f89d358c3e451ef5c843c071230a2fe30ec1efac1e58fb506267a50043fe6b9b0aedaae9208520d7285bffa2857d0c7d276e9b7523a1c22b8889c5295b5a539387d6738b996964071e25841edee21f1884ef73fe4c1fafa393dbeb0a6bcb56598762c554ac650797c90fccf5973fca168c3a9ccf0570a791c80be4840039083318589138f566ed5a0222e4af8ff3a3569e4dd5914644208b2289e790f15e5b4c3daf9d4033b4e1c77c878fee8493e5b0f6f4a4ff5657922c0642a7fef854e5a1620af30d8804abc4315cffb8e271991353556fd2e957c235e028c2afbf0a2c35a998cfe3c87f1e9bf0da9bfa73a67e5a6f3ab73c9ffd554c82fe52b742a25587d43fe6675915f2e509a7f0c6566196f4c5aae24bd495579026328a85f668f685466fdf7f76a8becd25b2cbbac3efb8306b2691451414407ee41fa1471055a2ab02f5ec99b2c612d0d1cd16f1af866e773d6aec53ed2dda0fb6bb140b766c0b3a0f8e6012b7d67554e7c7a1876f51d0cffbee1fc1a11d46257bfca462c7a9c17a4f872476b9aebe991846fcd10c431beba46f02cb0376a632c4b6e8b10cae1eff3d96224886c1d885a8c46d9dc80e6a5edcde5d436b902cb0565be77baad995411199151f5ea61ac1d7ca5014fc2ebc01a8cb9d1e7662dd93f253eee23f474bf3a25285c4e992a0f77e7c707a412d50e5a04f49f1069a9b810f2ddc9ec9f468c389279b75bddc6beaeaacee970c768a05e1ca667a796cc4a5acf756401959738079b0578a61a80c1329ab59bdd2bc62fa98178b3acb2972d47539d7b97bdae13a81be76eac592537d096902a248eddcc8200030df3f9a2963ae7c8a3a86e83595940810a619b063d9bc6fc0cb75035e988acac64480f5a1a31a787855d8a83013919a793d4de679a6810208aae6835ba9aae843e6cde97ec57296398ec3c128891f3c7e44f3fe0c9779350f66f55ec3be94f9eed53dc6ebfbe53ed427cc44089a70100e605f554f9410bbbf77adbad858ce214f06ab334228b8f894fb7a9b2e3b4b53baa67fd4311fb910c424cdc486e6739cd432a711f570699a903c52a7071c2948a5c6c9d125abadccd242e24c2871e83d7c048dd2da6a476466a9ec31a35a652c06be1eaea5b6820e87f880d9b2faf5c2a7e60355e4a941e1b748fba735d0e75dfec06c6a9f2e57f12171ec9d6c69c0fbe3c6808324175ab324efaba125a22cecb55d7be793e6799d6a8c2a64774ecf894b09ee626146d46ee5b6875e74459751e16b62a4feabc675d887910cea345bdd470fca4229237d4ff79b7673a974bac5da0cd2f3df6ecd0c21ea039acb0cfc74472a7a97a2116d3250f183d0e427228a9602fe6d39497b02713c61e478b5c1dc68aa0d1e0294d7a5bd9bf4b8182d2cbaa1b9455c2cd2ee1120c83166d6f2dddf1311f40168fbad45b1c7afab59b95077540e64b638c159dda711a35e0bcfbcdc89f8ee8da56d7dfa2e23f39e8dfca2033783a3380c031deef512177f7128400ca8f49d8cdcac9ee38a5f86b8ff90664418509fee67e383bfbb478d7434ff7a6f50f6b4a279be9ab33b7270658f129e4f56526f32b38887eeeb13e2b068bca0914e730397ce5003d181f777b45744bc43fd05141178878e2f2705017b4616d23ea244d54aadc74c4d8ef3cbca173964a50521b13cf235c4348930f1c7d17552bf9f89c988f977ed6078fbda9f23d81e117404fac83961b7d23a91c7de2a5aeaeedc8ebaee2f0f76d9327e81a1f23fddc05cc577e4c0dbfed207bea589963c00c96ad79f2360d470e3304ad86d203e1c24738973b46bf04609f1f744dd1975c0c7f7f4e7a337bffbe7c9e83fba1c69c6e18287f3afa2d3996ffc1bd5193ce2b52444fdcdb0b19f701297d88d0fa29962cec5d2ef399feafe95db1f5e8c3c645ae63750de0406d519710dbeaaeef4139aa1b9687f4cf3ff77cf42acc00833bded8e853cfe5ffb8a369800b227fdeaaf6f54c182aa21d1398b29016cc7d468424beef0f5babde8ec7b1b7259b0fa178d98a5e2e2a6f100fc9b2dcc4ee5ea49b240bac283c9e4657eaee6a3f266b7f091d30e96666c14f1285a8671d02656a3e5583d4a4850da032e27bc13845a807b36a974593b1d232bc7742f3f20d1111781746deb4ea6ac95653a1acdf4f649bc060044d3224147133b44bd88fb13caebc41b36f7e48ec97b21e405ec941b270960837be1d49179664567d1ee2342cef5f9e4a559c7b27aa5aeb094a60845308aaa9c2afe5fd4cb808a44e4b6211111a69b40862e530247320863b7fd37fa77e69f05e05a8c43b51d3dbbaf3c715e5c348abfcfc5673f8c21a8126c762325ae3cffae51ffd43cee880f480006b7ef63e3a9ac33e6389466ef1a0b0e67e47537db6bf0f4950f735df6cd81ac960084df5f17d827ab400c074f8fc09bc5353bdd8cd17c6dec09842e7fdfe283f7f33133b33b704da89184ac05b9f98f0b64a5a437647107438cbacb161b6ec97814f56928e800ae519efd7129bfbcbcd4b305a9c703ec4c2b7fc685030e741f951e182da0e0297f99b28a1adec735e4a8b571e79035b78513b6ec12d815323fda7ed61353c52d490186450359c7fda3b45258bf276ee655cebb8bb23b20067bb914cfa50510832e93be450dfb9b7938d3e9888632938ba8d52760169055359373a558a7e2db3e3f7d31476c638a263c48b02f73131c737be93f29b9d9612b6d91434a26e6bce2b536a16d866985ad835a995781cb72680b8a5ab806da807bc77b9ab0f5cc39e845e2be7599db544dccf61c214b998469e8e7e568db4d171b66eddcecfcbc74535753a1b430c91c64e4ef97fbb70bc2468173d0362940a1379d90b358806eb49c2632398b2572b3d821cb12c0fc32c68106d6357b26ea2cce6c6fa8e1a17bda0fa64820c450752483cd066900f36ecbfc34b100799756296d7e46e48c5c48d38cdf333b98a8c7aa1adc2b02b58a0189f2cd046a18d1778192d98cd9510b40fb35350361fc4c3e917ac19c372f196e52c976c083ed500b4238f636fe21b9f3c362bd2556b16e45f67de52aa2e8f08d92bc19fd18a0030591df154df34ef121eac4ab0cba5b5fe8920c4c3f3a63a20f439ea9dcda4ec0d7601fe8849aff4f5d4d5552cab4c73b34d41543551fe1008032d101fe1d94ab4943256471f4bd06eff1f9593afab9fa8cd534d88258936cc593785464f4546b268f6adfd878911497d035a60a0e6c68b5884d76bb4898ad59c41160321b83d40a364cb427699c201ad78852a22eaaef3d5ceaf9de365018b271e16abf0ff5819345ed4764b70b88decf41c15dd243d81cc599a2fef2a3befb2949f2ab244fbcd412432ad3600eb5d92d116ba618f8730a477debcb3280d8b1dc04bed8b360ec7bb47b9cae89d25e702db37c5b583fd72c3f0c08a1495f75f15982a9931fca16b5b1ef1868c50a855116e6e0f49495ef82705f3a3c8d834d1725f0f0506060c2cc37e148f78f020fc701424fe46a5159e3a73dc834433d244568bbae114f475e5e60c13f47e9e14db1d21d451d2c5f39c39af0b60651d059a899af0181ba0b4c7fd5a7e1416adfb9f5381b24ce947b7d09a27a264acf7f0fa28d9db6f6f277d86e94ed96a4a53cbd3a7fe099d7177c2d6ec783314e08947f6811d60f069a1e65663b93f9aba00dd7de119c550181262340a88b316c191cff1c7b43d936a466c0226a5968c2e84ca61faf9a32cb3170fb8d105d25b3952395426d28531797154875af2cd089f7505dfa742c83a9fd15ea57427767df5db894e58f7e026eb4d126067eca69c7c2440d9e12486c63957013961c24359f94f5c1dc239bf532998ca339b3f0053961fa7b71c3c2a614d4b8a821b5e1a5544c4d079e71a43a7965c34e981a1c5460b25b6831979883e48f76c7ed34c844406cf5268936c01c3faf13a235b72444b9d7a701fa9a495231fcd8b8ed89ff2993e7a0241f8ff77e71badc7f0c471024a240f4824da0ace63db199ded2e6f3953c43cec3f5d60394f546eeac40331aa3f466af470311bff164fc90b00995228cda7e239b354a10269904304436ffc6f42c17e9b9ffe9a946c205fc0add8103e12e342b4542062ca0083c286a0be8ad469885fa7171c5526e2baa153c8cb43d33e9b1db7c635827ecd26041aa632829acbe53c38f63462e4d7a308f299efd555294be0894ecebd3a11d4242e1aef59cf77768197b77282aa0dd81d9085f87daf6bba680e40aa252629e2668d87eaf38be0e5399c95eccf3af5ef5b6b9d9da27251b8375343aba5406c6ae8f78d2311828bac89fad2291433cd2ee74ffb81fee1a3170ed32305ee77b1ecd22c7dc6b7b5b400d42917275058a2be78bcd1d79a661aee6ade1ce17fb1cbdbafbe2dffd3884dd87e14e36fd4a27a5c64d4f970541a75af417dadc969e6bb5f29415070e1078071472b5e043361e5747809bcb83af5cc5bb17b03ec564ed1349b563563233760c4553b0ce46a6adde8b4f1cbcf0cc33ccf6d8ec8551144992a0f530b012ec11e28de9a3564096637e590d549b8264c3aa1284270a9310496fea8d53024853bf30801c657fc2439f0446b3de62e556754805a5618eb99e3ff6acc52c898900a565139dc593c4b2a37fa9e212b646d9f4c7fbb204c2401ea0d838a806dc26c067a390f202bd3446cfda0a569c1cbd99be00c125ff13e330bf7b67f8e489c2191d73a74d3cdebf0bbc20ceb4c024bed7069d261cf7418fd07d305b03dec683dea3e3ad4f1ef8df8073f720be0761ba4c6473ae3e8344f76e7e7530258aae63b0b183b0d364ff7b53d35bb0182f8cb56bd550a5148737a1e7520cdfa5b11f0caa70390ad04d0e98664d47af518d6972fd4f803e5b395a68a3e08df1ae70e0aec356075f616c8a60502d45fdd6444ac5ed5d37d2f6083caf91fc5d9851e636ceb095169d44bb865387a60ff46a277ab2f9f6d8160f09d051bb581c3daafd79cc8d2d307335a7505573d2ef74d0f66ab4a432488c215b6b72faa1b672c5805f0e3265583947fea3f20e6b1f10b4dd717c0ce3088fafebc16d48ad74ee4cf5e059164700d3f50df68f2fb8d8b932918ec820c0de00eda4caf332a1139924cb9549c265339495fa248164c422fd6a31337a78320c8c31193101a9ef7202fe0ce9d30521ac08f0f71b3fe100625ff22cf651ee9494101ffa3b4e8c8c360bf03ce35a6c00e3a0a7f024f9757b4914cead8b17a52669fc31bb92efae1513aaa3c109916ea7c025298036cbc91c69b7a53d5774c1c28c9356e33caf4a5d6e9809bc11de2b3bb3f0d2573f8c28c8320b8a397ee9e384dbcad1d8a99d70cadc1c337d6c9c2207fed9f62963c46c866c79fdd4abaee40b62ab54b942dc2da4cd87dc404b742eaec64ccd087d2b60e06b1396765390f6f8c254bba3b0d5bc015100a67319fd198fb2850586b63d2d2b728d47aef097893178195064925954678bf2d7e5e31bc10ab8a315a0289c8152e7ce3051df782d81b7c49e4f171f1de5255b87d4801b0842318f60dda27545eb0c8797f77eec5a064d166da02f04faf7d809219fdb082abb41e0a59eb0c8eb4e7f2a260aebe453c59fb18794fe1bf21eb9eb330740081873e0d674f026d261f82b8262c2979a6c8b17a7cedc89a737f7a5a43e68f513a9c0cb084fb4723d230864186c8e465db6eff89efabc81c7b511453503847d69efcd625afee62118c8172fac335c0218adaa22e0b6b7a205e1cb0ec4dd27c769fd626eda9952cc2887c3e4e7c2586977e7145bd175ca45ad507a6ddfeffda0555ebe142cffc93ff70623f8fde34f24c6f9d654671bd784bb31fd0dc11da9bfe4577408527ec385d71ea1d3b739101083594e4e63f4156eb6c37541555344073f25e39cdc7a39c5a659f560c9ceab686cfea58fb62a1fa4c7aa3a35d91d4ff284706054615d0782bbb6dfb3b07a5fc80df69f1292556f2ff044d1728be0a4604118386c199a19d467bcf118b5b07b4a52181c73d6bda19f8952683c56b61fcf096067f00e47cd106626aa6e3806a80ceeb33acdd8ae7390252c815629473d79abfa9368e0c6c546624a60b011715b87fb8d5cc9a1f028f1079ade65b35291bb0b1fa5f02b6072a40a78275e2ec4784e41d16fd83357ab084935f6d7896788ce7cba108896c0e865b303fed152a8ec3c664f4b135739a671d3a8335b1960a1727d451c85f0e5562fa021088eb45a7f694371d16c21f7b136b9642e817cad5135901de9122756bb776eac02b894d04e198ae881e0af62b79dab09db20311c83e69852ee7b5c13a546714dbceb221b0440af333c3c4344f4fc324c301a60d1f183e7330f110ed3596e253fa8c693063f5f9599faa778b1afbe68eb2f832af2a6acb250d7236e956d0fd56eded2ee11caa420a2687fdf82a74785366aa22e916d75ad1597ea3d2f9a0c5b6d07a4d557a931022bbdd36b4bbc75e97c3fda081facc8cc0782f902771166d34c8ea91147d1c7b7ec857881fdd5425581f1d027ffd2108ee15a9b81196b29059a5791850f6f330b47bc5c7180db701fa81da7030cfda8e60f12a69172bac1651b7392a0927b93b28b42b5d2e9d590e736bfad55993d97cb1b79a1f519591e2c528bfbd0e5504189719b9cf4f7b0d155734cd43800daf07357d653f73370a02618bae488201846aacb31565b5b23e7aa818e70b5ece5dfe1cbeb945e449f3d425065925505e62a8bd5ea20f21667ba834d8cc52026857cf176677a658c7db9e27b0e0e0c479031960b9b3f6d06026e2d87c60c7135bfd63b9dcb2c00e46e5f042393ba7ff958ee8fa72c2c9e9594bb2fa9162c38688dd77c3ff7695303ce3fc79953453e2e2c7fe02628e53c52036297c0c2ac5f4630919bd359bb69225eca419c6a6c89c071d6716c6ec0093fc65712c2e7dd0be6ef7c7417aaecc60f83088b64bc0f247d038e921cf6fd1e47a59da17d62ed646fcc502aceed35870eebcf10881cf0ff712c302bb4e7eeca684b49fc90de7e12bd211ce2e0421d698c59ac3984d71d9b02164fe9cbe95966c4da5f8c4800fdccb6bc09e4056af229619ab9ab723ef6592c6bbf83fcc20dabf9f49511c4311a1a97cacfc030604334583e6f5ab08654ab43d9392722f40a41dfbd6035a5edc25fbe72ec02ac6775795a1fefa99c18948f548be1a636ebd24b697b0a59c00071b73a90511911d27c0b00926a79902d859a40d7f0a77488dcf5af259e818d05d186b0474a4425ec3abeadbe310922acf1ec22a615874764511bf80d16bbedfcf837323283c84971f9bcdcac612942fd12dbd1beb8f6b658da42f50863366552738016491073e24ec7ed6f429706ae4b90816471af4031be4e492c8c2a08ff1680e3d3d934f2e0a3e42cdf7214e3ef59af7b39842988a1f4cad45ad0ad419d0382f766560b861959132e76806ed08d5322da000d39845feaf455bc306af95a7684eea71b4ac31a972220ea22f029977030314b9a4b21f8c402b0bf2f41da5bd721179d7672ae77f48f9f682ffdf5bab3588cf8a49d31c002b7adb4434cfc5a05488ef8f26ac80dc153fabd6cebe61a04c2428aa04e037c977441b1bb93ed431c914ade76b0c08cc887e3d590f1e2a50308fa3c54b22d92f9b8ac39d485cb84eb6ffa0a51718693f58aad932695e169b7e41a4f4ce021362241472d13e2ef0c569110fa5f0d05f244e3e6f9b8a706817fa592b2f9117e8c2defa18ebfd1563cbe348c4f8de0a16e7acd71735a657f75ff196605d4ea3fbb120e954701c8c59e0bfeeee38f7312307ebcee061b4226d3eda9aad6eb31d460a0d3552e156f3e86489dff4a03791be54a6925ee5b07d0545896106bc847bdd561146ef646aa91b879f0de706c740bfdb5d1c3a732b640731436a62c431187e775b4880a0b2275a312a894779212407be25031e403d9f36cbfe07418dff4dd9fa6379d110416697ee0c114d113c6f99e04cc37286c3d6851c5ccf781250e5d3049d93d1917723751d8672639f0bb854f87564af445ac5cb47a1fd35864b6ae446eb1e4806a6f3bc9e4ca4bd191cf9d4b56530735b16254b920afa2415329f673bf921e849f0aa7b8c51f0e5b40756d04c19a1eff8b622965ecacf183bb07b2b4572630f97f6eadda879bc0fffbbc4bff7ed1e5aca9a847de2129a3c935c278af6c29eebcf58a1e6cf093aa44aca35c1bafa6e2a361218b000ff4a2a49c65e64c12344d94c5040d1e737f8bd78bf015ecbfea6ce19574837c5471dd660e673dbd703eae068521ac27f570786a952e37d4ef425607ad60fe45b09a228f18ee664d04652ee2cbb488d42a0c9faaf50f867afa41f1b68aa9d7967f15adda81deb18c00f29ea8a5e0775381cf931f58caacb54a7ac41db043747a218927fbebff95aa1520e136f366088a0c006a2fe6b61070626e0c083ede8c423acfdd70d0de04927a5d2f481d4cbd2485c5bc7aa22f6fe226be46be4a9dfa6d10253675bf0760f3131a11e169dcc62f4338fdc35ce0280f23483c2ccd2ed854b3666f6e8c02ca15be940edcb11e996a84a61db5b0f68fc6703a0aed9866396e26895aae65bde6d50f573ba0a6e45a6671bea93700223b866360ec5baeef69294666acacd89acf029fd7e66b37d0d1fdd9aa0a69a827c6506edd8e48a771cbd698b868de3d4d4440348f97a0ab76709d57139a1da8f1b9543252bb8778eb2f5be0ed17756e4ae806e341741dc992dd2f06608eadeb4cd819ac791f0d30901e622bafee36b5409c091193e4c0f5a5db5c516cfd9e40496cf91773e6d87817f639f8d47385df3a43a2bef3705c25f636414f9c2887a782bd786b7b1cde6793907b15eed4e9486c991f21e3a02f7d48dd9366ff8760d95a46751cf1d32c2e72515f36e0d98ad9a5f81a70c06d5c4560868c6d1990def3b94475b76664381f722fdabe739066c58370aa03a28aa5bd00432177b74d70f4cb53ab7f3a5459e99e1b430d1dd547c273214dbed7c3cdc673a0f5b924a860cce78aa1e8cca714b5f28471368e2fb5f41d2e72e6967e20adbcd5006dd31f644b4439ecfd62541f69d5c9810ca00df676a284d4646923f76dd4846d7f289d29cf3dd9770cc4fc2a2fda158264538584aabd66d28f71018252892b545992ddcdf4a40fa2f3a909abfe0da2e722178d70e83ccd21477581af360c93d33531b095951804c15f2dbb80d48a9db7ea9900edef9651f758c97683eaee8e61c0c88d30c4969920aa732c57f8c5a1aa2834b9f9c3285267dc4e56a381633d466a64b2085abfa052b13d812a6873efe6f2544650186fea789d6924599bc06046f151931d7b6b614b836a1246b8ae7ce4614563ecb68cf9a57cd3731f89e1a73951a2ace26289a366529a987592d18d4d326fd0a9f289a6a9517d4e33de1736ea2f9c5e2c52493378bfd5b4fb643eb17fa154728e29ddc1b2d6fea380205692aac60d3916ec163777a6fbf2fb8cdf840e09f910e29c85727812a62dc3a3a39afdc2ea167a5449e12c2ce1371a32d57ce5802cda1f28254f0d9c544080622df00e2c094011ea97e34edd702de6a84c1b156da47667699b63ada7d58c202fbc2f540c8d4fbf8cdc95f9b102257fac1f2f8ce5bfd2f50e99f7282d2463208c08b106782a1ebd4a135ae1afcb54319972689303d6a524307e29114a50cdb2f8c94fb0f204f637a16fea8261ae51ac33b3b1ab498213636b9c7f855b9a46308ffa1f8b6c8b25a2b6065920f9a20833f9c097b8f48dae00ff898d7d462e55dab5aa07f9d1396504b8e42eecec392fca1f64c30305e02602f5b454c4a562bb17aab60970d440d913b8db0aae3383e1f3f013d7019e3e9d69147810546b1dc6fd68c9f47ac3c4a67972b854055f4706ae4861e584aa855d42e4b5dfd61fd9d6673beb5801d2e31bd7dd78091d474d7ade651dbe5ea208360be3ef1aeebd9e38681768c0783193d1c4474f913a2b4c395ed725ba539a6d6a0ad31015248c84805bf0cd35449653e8801a6a397f228d385e8cc8da401fbc8c111de9dde1257c0cae82220202870abc1a1112b807287b06d08f9d33ff02e81a19fd66f02ce48b71524b5a5177f80b3674105d56234bf717bf682f63943f9a6464638053561b78db54aeb6525035b39a01e610249af2c0b5f2b3b799f14f8c0ee76b66f09ac685ed9ba4678268441d14a22a4a65fd3d7d72816af4d842bdcef9bd20ecbbb42c6b6fd6668bcb0cc8c99fe5a30ae7ee5c850bec2d6296f91c2c1976fa55a4c9cbdaaebdc8f718475951affbe88c3af773953001c08ae069e1cf40bb9799f569954b33c3f4330c74652f088ab669c8b7cd93c5557be761764be9e85b0f07439d28b8e9977586922dfe4c287bdc4122fbe6378923c86bc586fb547b1012f92b2a75047f7a48f88e1730408bf53a6b6ea2c905d1807916be1e0288294cc466ee73f909ead23f31ef36b61e5df581f382c81aabc761f45547288621d16ba21e52c14b92c93e276c22f2b4ce5106928cdd0cdeb67dcdf8ef98db1a701e9f196a2cf3353a27bdcfd5ea32f8cb53795c40beaec2e33bb3ceeb980688709a6f875a2ea891367aa7b1d5b5de2f90d717d2efea3a3ab71777d1f4c7d758487f2114f5ad4062b31b08fefd3edda89982138e4185ed9f4cdd122761389e06bd4eabf217d4197b3fa1a0691a96f7b1ea33624e528132c104b25f0440236ee38df45c1581a68d1fb44e1bf29c3a191cc95ecc2fe09c38c78bba281cf51d51f06a22ea1cd6476b077c6deca2c278606fe8d6efd65dcf9fcbb7e984d75e69ee6e1989427c510034fd4501f75ffbaaf813bbbeb148dd1019d45e2e6ad33a22304f9cbcc54b78c8c3ce958f8a75a2a777f092dbe3b88344f84d93dc9bbec0aa9287a9859c740dd4dd7bf28e5222cabd4a525260a94996ab21d70c4c82ae42d7c802dc9e7377be23b15e5c13872b0a49ce3894c60bd1aa235fcff8d4af6fb85656376a5fd0409fc4b33419f9a4f70462baa3534bb8ed68b8ca471adf0e11d5ba51d4b614b678231e3036fbd5c632d956298ea9fe845727486896056d0c03ccdd1c9e8a9a60473db4e6face0c4edd3d0353fc588e24e6b428050f18974d8c85c7cbe95dab305b6720dc14c21b1550743e335263c756399ff8091f48da7cdfd9e1fe4790cb337e8db7640f2916fb910bce94e76c9dba93ce0c72c297c340c76da7895a75729b2e103646d91170978de2abb1544927d473113947c2fc1e048cc08bde0fe3e5e0afb144fde4fb7328545b05b100e432ed26d16e435fe4d6c0a4413a8041614569ccaf741e8d3e4eac01490c890fa924792a080750f582a538afcb5851be494f8bfb0649287fd01b5fe10f7402ec63899c67ba5c2d377683425d4b079b62e13e6debe7d6cfaf1f7e8f6def16902a725e89840eeef41fb54d74e97777a31e5275cbe2c6b49428cc11c34a334f967c3be7c8228b77029e494a7f30f0f774f9d7b3ac9cbb0792e5af1b1cc7bf8250b879a558fe1dcf0e47f9eed867580bed13bf0880693a1eac8eefa43ad554f64f8c07aebb280f71112a168c320b4a2cb757c2f0aba3f7168c4dc1ad9a95a959ebee8c4057eb6a67df2d80a815291ab340fe4e1c7edc4ea32ef97eddc3a1806d4da1edc07ab7362a215be04c47d9d204f644ac4463a9aca3b6620cae9842a2c4140c724fd7f73ea8a7adb19143907af6e3850a5851334062cace2722124fa72935979ddda0aaf71b3d0cb11b3ef12e955e87ce03bef2f686354b8023b45933787146beb2844f6bbb3e4e6278270b700e73b3b2c4513a9e8de1fbc15ca0f7b76f5386acddeb400452b6fe7e60d109ddf62a3404b1b3738de303d0e824796e1737c35e1077af37d5f8d915c8ab71a16635c60e18d76b3c9280d876a34fb0973b87ffc3d4761075e1f30a2be34621baf1c73cdffc7f965e590a63ad34897c27047df2140c976b62c7cc9f02fcefd07d9c0ce7ddeee9cc6dd7b20245a7a08268e2246044e84474969e1eb63930f495750917bc0975a0c65feb4d5a1d87a2ea7e1508cb2436f319adccc4618bf5bc1885d0e1fd3f254d5779037ecca9649879f1236cfd843bc832c2a7c2d79e6775fffa67da8bb582e400b36a5b95a7efd3bc6d33dacc0e2588c713fdb46c87095b629294efa9f197784766cbc697b84c874ff109705f2c0b6c2570b3d90f5b85d84a5e1ab2a037136d187e37a7cb33b406b3011fa3897e649ee63ab76022db7dd2d0eb1b7ae97088b19634ff9970bc1cedd6d20f5c67772e8096c634a7dade70f5f92710e41ee9d8dc3515d7d1d73a8a6190e1db33e2066bd26a9e828a1b8f90f7ff12a2f23627f75fea4164c19ec1ac04b942e6f2013bfe2c2e43c2b57f3b21024429b468c6d1a1dff7540614abd4bc82d5d9b059bde8b1031f96cda606fe9e94136b4290bd046c5e2818ecda86bb7e1fef74caebae4d090b6a58e12edfe52362a681dc64e378ab008550c883fa84b062b778fe2db472f32ca3fb2f74df7be06ef0a85f2fa019260c5cc1e66d7fe6d6962bf8762e9149a689749f3b871e88e5a8d4a61490dc8c701dc8ca3e920067613e907f5c736d68c792672895b47e9e797d0253bec32b9d5a79e0a433e1601d5e5072b7660b5ebed7e67bc95a6223176625290382192efaff0436ff1c704e9f76e1c64d83fed9472197a6bc000bcc24d02e5400efee09bc5881aee9bc801826cde13fc6d22a0a9dbfe4cb171c9528a0240b8ded6f922c77de1360939fa0bbe4fb82c3105f22c90040958b1cfad71423aa7fc3624e0d22a4e9da57e3dc09950a599266fa71c0841f80764e96a096e1ce4ad161c0cb5348bb5248513b4740748d10b423b9cbc95cbe6ae43040a5eed2ae2cfc7eb34081595ab6b2dd1fd7480089ee2e8fbcd06c6dc43a3243c9c4450f05c28559df8c0fc41cadb644854825662d1475c00dcec00818b746a286dc12acc5175a04d0ab685b48c76b40bd0790afa606be65e6c7df5e027f8bbd6979f00a08cb985b68a64f1604e6386715a4aa242d8176e43f6d8147dd64377a4f44d24fa3ed06323746207d95bf6323b61b42f4903d32f6235a77f98c25ce6ebe8d5f8b76d689267ecffe9c32b7dde34c7f43da41ce215456f1423572b78b116af081226c54eb0fcd8272890ea4ff1ccf91614c309cace805da498eb7b538f2f5e08d99f46d1f57981c5d8488301fd00d11f484e13c00bab448bdace012d2951db621aea02e2a1efd5638931f55faaa0c62e9a3d25ee26ef6a57ff22836b331e9d4d9179d5297972891bcdfeb695e9d296e61798456f9c7ace85c8e767211c5b586eaa114c74dcbcaaf8acc932707f42c775032e1f771428bb60c6fbca0e34e17a20ff52f4616516c60ff59a0b81f9908faae30985bb3126f98fd57aefe7e5b62098f47f35be80891ce4f9c4c6991b817128e3917b91d6fddb764b19e9e705c9fc3b45d1bb4fd4e0e06aabb40ca9f276f618e98856fa6eefb1646070e7504247df6dace32b472aa7dc41e633f086ab7d4ff34874c544d07d5679e7a8ac5f36672cf59ccadcf0c002e9f9322ca34a1691690a06b2f6dc2dd5d1b705490c8bd3acadea5d4e7dde44bfde584a62bfc85ad067be0e3a733e27ce017cac0230bfa5c53bf423dbd2f02ef0b95678a215afdd0480d0f1d7a1c709398e3448eb7b7c77c33570dfe545a81c6984c1bf19584953641daa62be86c17ae3b0c39daa12e0ddc5c40998f64abea505af6ac562d79d5f33cc19954348b0ed03028e71f6ee00962b0a3cbfc3ed78e92b58da538e8d4f65699a96bc41987f1b13aeaeb6fabab6b9bc9bb9e30ebb96a7a5817b73061d368a356f3d332e77da5e0f16d5f4fd981c132ca92cf6f6ad0f6ddbbb8f20912c4cb8a806e3386f39b7c5f668763366d01a4d69b5b0516b1b8b0930e7211cc060ef0d0de91e49656ffa28cb3ba42f4c2a31892eb91effff5f607b3bbcbc61733e8eff2680547ba75f37d4a7a6fd49019dabd5844aa2077dc5783919beb2c0a1f2601eaacc0ef67d61a70a8c9c248de2af03294e86f555ec59ac8c86d78a35c450ee80d7bab2b72761412cb54250b27aa3dd40b23532ecb3a14fd7fb6d0ab584a3677f6b1a373a1400100439edb5e011c9595daaa69fbccbdd1621f8ea08f21d4ba9dec01f2b75b6579f5010bf6538de8240a266eefd7e2fc9f2096c23465b5d545627737f162f8c5691c0eb07fe59879d55fad9174ada4043b9ccca80e2c9919d005e339f71802c6e64107e5d939921989642da4e3a24ee3d58ef82e99a54a4d4b2c732d114a823d6edafede047b8877713abd0a37da3086c64abd0cfbb2914d41fbcb6c33daf9405e371dca44f9b085bd7ce80ce5dc10847111cb72a6fa0ddc4d4f5fa7284c4becc389936cddbd759338701adaddcdc68be01cff14f472d30aea3189ae4dce09afbdc6d41405e16dce2f667bfba5600d7cbdec3d4d30041544dd461fa876c085c15de206ea8a00b90f89b5b010622d246b63a11dd57780c09e6e66288141e5191c9aa4d3887989cf2960b5f7d7d0a00b4fafe80691e335e8836cafefb784c05c4c13542d47123df54b71503998f750520e6226690a6d0e933adad8555f519c8e08d4835ff8826d9e975ced67b2084b5f20c5e2e2de0f32bd0cb3bc760174c9e3d383a4d45af9505d2c1cd4ea892cb0190d0ec47f1269623937425aa3725366ac712f7e30358de56b757912fbab0e73dd0d5672f0e23ae501930c7cd82b10dcd41815ce7135b8013e8a5ef854dca11b7c984d9da15547820604df6d0e30b896da0ab8329306220a4d095c610566196961f840733f872dec575ae58c11cf507248d3a5a017bef3c939bd05b789a41fa6d0ee0e41b72e62aedefd033cceae2e13404eaf2f3ba109c6cdb10cfa8b4e6a78ac3ee7978a273c999bca8a58930f4914044ba6605638ef5dff33b6b4b1fc7cd76ce502060affcb5232760f8aecf01825c14e3d1c0332b98a01747965b8e62c1cba3a865754aeeffc1a3fe38683a0ae89f7320b1ba314f1bc5dc2b47b094ba9242e7473245e6feb8e5fa63699f320c755e4b81f8fdc22d277d62d50bf1ac0a33047b7ef43c9eaad8376e3049b7a772cd5a21fa3a1358efa46857699cdf4e26ca3541f8a508b9f4baead07e9b8522081461f3a965547dbb7a43cd53f804419bb9ecccd7e0be09f69b07d320d52db53be1be2f6b4dc4ff8b7665681e9ba4cc8b6ac989bac9002a15913d0600e7100cd086494fb0d44da52a13627adb6089d8634288b08e9843ce090e79c37a286d9facda1126adc9bcac24faf62650f793407c36bb71a4e26526c7c84521aef3a7c702773ec2e4d9648a2269d86002a11325dd8eebabd321a4f6478cb670b8fc5b1ec5346b58e57915a776dd1830854a81f2716b089a336d3c4c9bde6337c9ebb94f269d9990028c04fb12ca59c2eb490470e33534d8efb250b518d7e2b23d515a716905e8e5200343adb21ee504195f282c913534a76452a49c76b8f5c33a8a174f5052dc3db943565e6fccbc36e7951a1063c8410a454b7fad8e54a021340062d2fdf94981dd6d88995014a11a7dbe244b401ff88d6f780ae1c0945d4fd88c2c3426296bc2c80");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }
      */
    public void testSLHDSARandomSigSHAKE()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_shake_256f, new SecureRandom());

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initSign(kp.getPrivate(), new SecureRandom());

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        sig = Signature.getInstance("SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSLHDSARandomPrehashSigSHAKE()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("HASH-SLH-DSA", "BC");

        kpg.initialize(SLHDSAParameterSpec.slh_dsa_shake_256f_with_shake256, new SecureRandom());

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("HASH-SLH-DSA", "BC");

        sig.initSign(kp.getPrivate(), new SecureRandom());

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        sig = Signature.getInstance("HASH-SLH-DSA", "BC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    private static class RiggedRandom
        extends SecureRandom
    {
        public void nextBytes(byte[] bytes)
        {
            for (int i = 0; i != bytes.length; i++)
            {
                bytes[i] = (byte)(i & 0xff);
            }
        }
    }

    public static class MyContextParameterSpec
        implements AlgorithmParameterSpec
    {
        private final byte[] context;

        MyContextParameterSpec(byte[] context)
        {
            this.context = context;
        }

        public byte[] getContext()
        {
            return context;
        }
    }
}

